API Reference

Client and server package for VDMA 8722:2024-04.

I++ DME - Dimensional Measurement Equipment Interface.

class pyippdme.CalibrationAware(*args, **kwargs)

Optional part of a ToolHandler: which tools are calibrated.

False makes Tool.Alignment and Tool.AvrOffsets fail with 2000 “Tool not calibrated” (Tables 114 and 116). Without it every tool counts as calibrated.

class pyippdme.ClientHost

One connection to a server, driven from any thread.

connect(host: str, port: int) → Future[None]

Connect over TCP; the future fails with the connection error.

connect_embedded(server: IppDmeServer[Any] | None = None) → Future[None]

Start a server in this process (default: the CLI’s --virtual machine) and connect.

run(text: str, on_event: Callable[[str, ParseFailed | Acked | Received | Completed | Failed | ConnectionLost], None]) → Future[None]

Send one command line; on_event gets each step. Commands may overlap.

run_lines(lines: list[str], on_event: Callable[[int, str, ParseFailed | Acked | Received | Completed | Failed | ConnectionLost], None]) → Future[bool]

Send the lines one after the other; on_event also gets the index of the line.

Stops at the first error and returns whether all lines succeeded. Different calls may overlap, so a long move does not block AbortE.

sensor_info() → Future[SensorInfo]

Return the active tool and how its raw data is delivered.

acquire(**options: Any) → Future[ScanData]

Run DataAcquire with the active tool and fetch the points.

run_sequence(lines: list[str], on_event: Callable[[str, ParseFailed | Acked | Received | Completed | Failed | ConnectionLost], None]) → Future[bool]

Send the lines one after the other; stops at the first error. True if all succeeded.

class pyippdme.CommandContext(tag: ~pyippdme.protocol.ast.Tag | ~pyippdme.protocol.ast.EventTag, state: ~pyippdme.server.registry.StateT, registry: ~pyippdme.server.registry.CommandRegistry, backend: ~pyippdme.server.backend.MachineBackend | None, csy_store: ~pyippdme.types.csy.CsyStore, cancel: ~asyncio.locks.Event, sample_surface: ~pyippdme.server.surface.SampleSurface | None = None, raw_sensor: ~pyippdme.server.surface.RawSensor | None = None, motion: ~pyippdme.server.motion.MotionModel | None = None, tool_handler: ~pyippdme.server.motion.ToolHandler | None = None, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, emit_event: ~collections.abc.Callable[[~pyippdme.protocol.ast.Tag | ~pyippdme.protocol.ast.EventTag, ~pyippdme.protocol.ast.NumericData | ~pyippdme.protocol.ast.PropertyData | ~pyippdme.protocol.ast.Items | ~pyippdme.protocol.ast.StringValue | ~pyippdme.protocol.ast.NameValue | ~pyippdme.protocol.ast.Xml], ~collections.abc.Awaitable[None]] | None = None)

Everything a command handler needs, besides the raw argument tuple.

backend: MachineBackend | None

The Scanning class’s real-hardware seam (see pyippdme.server.backend); None if the server wasn’t given one - only a problem for a handler that actually needs it (a Scanning-class one), which should check and raise a clear error rather than let it surface as an AttributeError.

csy_store: CsyStore

Persistence for named coordinate systems (6.5.2); see pyippdme.types.csy.

cancel: Event

Set when this specific transaction must stop as soon as possible (e.g. the client sent AbortE()); see pyippdme.server.backend.

sample_surface: SampleSurface | None

The synthetic part PtMeas measures against, if any - see pyippdme.server.surface. None (the default) keeps PtMeas reporting the commanded position exactly, as if nothing were ever really touched.

raw_sensor: RawSensor | None

The simulated optical sensor DataAcquire uses, if any; see RawSensor.

motion: MotionModel | None

What carries out a move (time, limits, collisions); see MotionModel. None: moves are instant.

tool_handler: ToolHandler | None

Tool change and qualification; see ToolHandler.

network: Network

Where a handler that has to open its own connection or listener (the raw-data binary socket, 6.17.2.1) gets it from; the server’s own Network.

emit_event: Callable[[Tag | EventTag, NumericData | PropertyData | Items | StringValue | NameValue | Xml], Awaitable[None]] | None

Sends one extra data message tagged with something other than this transaction’s own tag - the seam a handler uses to push an OnMoveReport/OnMoveReportE daemon’s report (see pyippdme.simulation.classes.mover_class) alongside its own normal response, without that daemon’s EventTag being confused for this command’s completion. None in a context built outside a real connection (e.g. a unit test), where there is nowhere for it to go.

class pyippdme.CommandName(*values)

Every command name a built-in command class registers, grouped by class.

class pyippdme.CommandRegistry

Maps method names to CommandHandler callables.

Populated by default with nothing - IppDmeServer registers whatever command_classes it was given, typically starting with the mandatory Server/DME classes from pyippdme.server.classes (see pyippdme.simulation for this library’s own bundled simulated classes, none of which are registered unless asked for). Additional command classes can be registered the same way, either by calling register() directly or via the command() decorator. VDMA 8722 6.1 requires any command not defined by the standard to be prefixed with a two-character company namespace; register_proprietary()/ command_proprietary() build and validate that for you (see pyippdme.protocol.namespace) instead of registering a bare name that might collide with a future standard command.

arguments is optional, spec-derived metadata (see pyippdme.protocol.signature) used only to answer GetSupportedArguments(CommandName) (6.4.1); a command registered without it still works normally, GetSupportedArguments just cannot describe it (0506 “Argument not supported”). Pass arguments=() (rather than omitting the keyword) for a command that is fully described and genuinely takes no arguments at all (Home(), StartSession(), …) - arguments() distinguishes “no schema on record” (None) from “on record, and it is empty” (()), so GetSupportedArguments can report the latter as a real, supported, zero-argument command instead of “not supported”.

register_proprietary(namespace: str, name: str, handler: Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]], *, arguments: tuple[Parameter, ...] | None = None) → None

Register a command under a two-letter company namespace (6.1).

unregister(name: str) → None

Remove a command, e.g. to drop one a chosen built-in class doesn’t need.

A no-op if name isn’t registered.

command(name: str, *, arguments: tuple[Parameter, ...] | None = None) → Callable[[Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]

Register as a decorator; arguments means the same thing as in register().

command_proprietary(namespace: str, name: str, *, arguments: tuple[Parameter, ...] | None = None) → Callable[[Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]

Register as a decorator; arguments is as in register_proprietary().

register_property_resolver(*, setter: Callable[[CommandContext[Any], NamedValue], bool] | None = None, getter: Callable[[CommandContext[Any], NamedValue], NamedValue | None] | None = None) → None

Let a command class handle a subset of SetProp/GetProp properties.

SetProp(Tool.PtMeasPar.Retract.Act(5)) and SetProp(Part.Temperature(21)) both dispatch through the single Server class SetProp/GetProp handlers (pyippdme.server.classes.server_class), which is the only place the wire format actually names - the standard does not prefix commands by class. Rather than every property-owning class (pyippdme.simulation.classes.tool_class, pyippdme.simulation.classes.part_class, …) overriding those two handlers wholesale, which would make each newly-registered class silently clobber the previous one’s property handling, each contributes a resolver here instead; the Server handlers try them in registration order and fall back to the plain per-connection property store (generic_set_prop()/ generic_get_prop()) if none matches.

register_property_children(handler: Callable[[CommandContext[Any], str], tuple[tuple[str, str], ...] | None]) → None

Let a command class answer EnumProp/EnumAllProp for a subset of references.

Mirrors register_property_resolver(): EnumProp/EnumAllProp dispatch through the single Server class handlers (6.3.1.1), and each property-owning class contributes what it knows about its own references here instead of those handlers hard-coding every class’s object tree.

register_daemon_stopper(handler: Callable[[CommandContext[Any], EventTag | None], bool]) → None

Let a command class handle StopDaemon/StopAllDaemons (6.3.1) for its own daemons.

Mirrors register_property_resolver(): StopDaemon/ StopAllDaemons dispatch through the single Server class handlers (pyippdme.server.classes.server_class), which have no daemon of their own to stop - only a class that actually starts one (e.g. pyippdme.simulation.classes.mover_class’s OnMoveReport/OnMoveReportE) does, so Server dispatches to whichever registered stopper(s) recognize the target instead of hard-coding a specific daemon-owning class by name.

register_session_start_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to StartSession() (6.3), e.g. resetting a modal flag.

StartSession itself (pyippdme.server.classes.server_class) knows nothing about any specific class’s state - a class whose commands establish a documented “reset to this on StartSession” default (e.g. Alignable_AB’s UseSmallestAngletoAlignTool) registers a hook here instead of server_class reaching into it directly.

register_session_end_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to EndSession() (6.3), e.g. releasing held resources.

Mirrors register_session_start_hook(); see e.g. pyippdme.simulation.classes.rawdata_class’s buffered acquisitions, which EndSession() “implicitly deletes” (6.15.1).

register_clear_errors_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to ClearAllErrors() (6.3), e.g. resetting a modal flag.

Mirrors register_session_start_hook().

register_home_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to Home() (6.4), e.g. Mover’s implicit DisableUser.

Mirrors register_session_start_hook(): Home() (pyippdme.server.classes.dme_class) is mandatory and knows nothing about any specific class’s state, but the standard says it triggers side effects on other classes anyway (6.7.1’s “Server Remarks” under DisableUser(): implicitly called by any command that physically moves the machine, Home() included).

arguments(name: str) → tuple[Parameter, ...] | None

Return name’s declared Parameter tuple.

None means no schema is on record at all; () means one is, and it says name takes no arguments - see register().

class pyippdme.ContourBackend(*args, **kwargs)

Optional part of a MachineBackend: follow the real surface of a part.

For the five unknown-contour scans (6.13.2.2, Figures 35-39). See pyippdme.server.contour for the request and trace_contour() for an algorithm that follows a surface given a function that probes it. Without it those scans fall back to a straight line towards their stop element.

class pyippdme.CoordinateTransform(x0: float, y0: float, z0: float, theta: float, psi: float, phi: float)

A rigid transform from a parent CSY to a child CSY (6.5.1).

psi/phi are normalized modulo 360 on construction, per 6.5.2’s “Psi and Phi are unlimited but ‘normalized’ by the server (modulo 360)”. theta is left as given; callers enforce its [0, 180] range (error 1007 “Theta out of range”) since only they know whether that should be a hard rejection or a silent clamp.

rotation_matrix() → NDArray[float64]

Return the rotation from child to parent coordinates: Rz(Psi) @ Rx(Theta) @ Rz(Phi).

The standard (6.5.1, Figure 12 text) defines the transformation from the parent to the child CSY as p' = R(phi, theta, psi) . (p - t) with:

R = [[ cos phi, sin phi, 0], [-sin phi, cos phi, 0], [0, 0, 1]]
  . [[1, 0, 0], [0, cos theta, sin theta], [0, -sin theta, cos theta]]
  . [[ cos psi, sin psi, 0], [-sin psi, cos psi, 0], [0, 0, 1]]

Those are rotations of the axes (the transpose of the usual rotation matrices), so the child-to-parent direction this method returns is the transpose of R, which is Rz(psi) Rx(theta) Rz(phi) in the usual notation (phi and psi swap places).

parent_to_child(point: tuple[float, float, float]) → tuple[float, float, float]

Transform point from the parent CSY into the child CSY: R . (p - t) (6.5.1).

apply(point: tuple[float, float, float]) → tuple[float, float, float]

Transform point from the child CSY into the parent CSY: R @ p + t.

inverse() → CoordinateTransform

Compute the transform from the parent CSY back to the child CSY.

class pyippdme.CsyContext(active: str = 'MachineCsy', transforms: Mapping[str, ~pyippdme.types.csy.CoordinateTransform]=<factory>, rotary_var: NDArray[float64] | None = None)

The coordinate system a client works in, and how it sits in the machine (6.5.1, 6.5.2).

This is what a server needs to turn the coordinates of a command into machine coordinates and a result back into the client’s: the CSY the client activated with SetCoordSystem, the live transformations it set with SetCsyTransformation and LoadCoordSystem (by CSY name, each relative to the one before it in CSY_CHAIN), and, while the rotary table’s own system is calculated, that system’s 4x4 matrix:

context = CsyContext("PartCsy", {"PartCsy": CoordinateTransform(100, 0, 0, 0, 0, 90)})
machine_point = context.to_machine((10, 0, 0))
client_point = context.to_client(machine_point)
probing = context.direction_to_machine((0, 0, 1))   # IJK, tool axis: rotation only

Points and directions are separate because a direction is not moved by a translation.

rotary_var: NDArray[float64] | None

Matrix of RotaryTableVarCsy (the rotary table’s angle) while it is calculated.

matrix() → NDArray[float64]

Return the 4x4 matrix mapping the active CSY into MachineCsy.

to_machine(point: tuple[float, float, float]) → tuple[float, float, float]

Convert a point of the active CSY to machine coordinates.

to_client(point: tuple[float, float, float]) → tuple[float, float, float]

Convert a machine point to the active CSY.

direction_to_machine(vector: tuple[float, float, float]) → tuple[float, float, float]

Convert a direction of the active CSY to machine coordinates (rotation only).

direction_to_client(vector: tuple[float, float, float]) → tuple[float, float, float]

Convert a machine direction to the active CSY (rotation only).

class pyippdme.CylinderSurface(point: tuple[float, float, float], axis: tuple[float, float, float], radius: float)

An infinite cylinder of the given radius (mm).

Centered on the line through point along axis.

class pyippdme.ErrorSeverity(*values)

F1: default error severity classification (Table 4).

property requires_clear_all_errors: bool

Whether a client must send ClearAllErrors() before continuing.

class pyippdme.IppDmeClient(transport: LineTransport, *, on_line_sent: Callable[[str], None] | None = None, on_line_received: Callable[[str], None] | None = None)

A connection to an I++ DME server.

Use connect() to open a connection; the client then reads responses in a background task and routes them to the Transaction returned by send(), or to unsolicited_events() for E0000 events (5.5.1).

allocate_event_tag() → EventTag

Reserve the next free EventTag.

For a caller that needs to send() a daemon-starting command itself (see start_daemon() for the common case that just wants one and doesn’t care which); public because knowing which commands start a daemon is protocol/library knowledge this class doesn’t have (see pyippdme.client.interaction, which does).

send(name: str, *args: Number | String | NamedValue | EventTag | BasicName, tag: Tag | EventTag | None = None) → Transaction

Send a command and return a Transaction to await responses on.

Pass an explicit tag (an EventTag) to start a daemon whose events should be consumed via Transaction.events() after the initial transaction completes.

async call(name: str, *args: Number | String | NamedValue | EventTag | BasicName) → tuple[NumericData | PropertyData | Items | StringValue | NameValue | Xml, ...]

Send a command and wait for it to complete, returning its data.

Commands wait for the Ack of the one before them (5.4.3), so calls made at the same time are sent one after another.

async call_streaming(name: str, *args: Number | String | NamedValue | EventTag | BasicName) → AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml]

Send a command and yield its data responses as they arrive.

Unlike call(), which waits for the whole transaction to finish and returns everything at once, this is for handlers that stream results incrementally (e.g. ScanOnLine); see stream().

async start_daemon(name: str, *args: Number | String | NamedValue | EventTag | BasicName) → Transaction

Send an event-tagged command that starts a daemon (5.5.2).

unsolicited_events() → AsyncIterator[DataResponse]

Iterate unsolicited server events (tag E0000, 5.5.1).

exception pyippdme.IppDmeConnectionError

The TCP connection to the peer failed or was closed unexpectedly.

exception pyippdme.IppDmeError

Base class for all errors raised by pyippdme.

class pyippdme.IppDmeMachine(client: IppDmeClient)

A typed facade over one IppDmeClient connection.

Groups commands the same way the standard’s own object model does (one namespace per top-level object), so callers work with typed methods and values instead of building/decoding raw pyippdme.protocol.ast nodes by hand:

machine = await IppDmeMachine.connect(host, port)
await machine.start_session()
await machine.cart_cmm.go_to(x=10, y=20)
position = await machine.cart_cmm.get_position()

Anything not wrapped by a namespace here remains reachable via client directly (machine.client.call(...)).

async classmethod connect(host: str, port: int, *, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, on_line_sent: ~collections.abc.Callable[[str], None] | None = None, on_line_received: ~collections.abc.Callable[[str], None] | None = None) → IppDmeMachine

Connect and wrap the result.

network, on_line_sent and on_line_received are as in connect().

async start_session() → None

Shortcut for machine.server.start_session().

async end_session() → None

Shortcut for machine.server.end_session().

exception pyippdme.IppDmeProtocolError

The wire data violates the I++ DME grammar (5.2).

class pyippdme.IppDmeServer(*, backend: ~pyippdme.server.backend.MachineBackend | None = None, csy_store: ~pyippdme.types.csy.CsyStore | None = None, machine_class: str | ~collections.abc.Sequence[str] = 'CartCMM_TouchTrigger_Fixed_None_None_None_None', command_classes: ~collections.abc.Sequence[~collections.abc.Callable[[~pyippdme.server.registry.CommandRegistry], None]] = (), state_factory: ~collections.abc.Callable[[], ~pyippdme.server.registry.StateT] = <class 'pyippdme.server.registry.MachineState'>, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, sample_surface: ~pyippdme.server.surface.SampleSurface | None = None, raw_sensor: ~pyippdme.server.surface.RawSensor | None = None, motion: ~pyippdme.server.motion.MotionModel | None = None, tool_handler: ~pyippdme.server.motion.ToolHandler | None = None, on_line_received: ~collections.abc.Callable[[str], None] | None = None, on_line_sent: ~collections.abc.Callable[[str], None] | None = None, on_connect: ~collections.abc.Callable[[str], None] | None = None, on_disconnect: ~collections.abc.Callable[[str], None] | None = None, max_pending: int | None = None)

An I++ DME server that registers no command classes by default.

IppDmeServer() alone registers nothing - not even Server/DME - and needs no per-connection state beyond the bare MachineState. Pass command_classes to register any mix of pyippdme.server.classes (the two mandatory ones), pyippdme.simulation.classes (this library’s own bundled reference simulation - see VirtualCMM for a server pre-loaded with all of them), or your own - each element is a register(registry) function applied in order:

from pyippdme.server.classes import register_dme_class, register_server_class

server = IppDmeServer(command_classes=[register_server_class, register_dme_class])

@server.registry.command_proprietary("XX", "MyCommand")
async def _my_command(ctx, args):
    ...

Section 6.1 requires a two-character company namespace for any command not defined by the standard, so prefer command_proprietary() over command() for your own. The standard mandates Server and DME for a conformant implementation; this is not enforced here, so intentionally-partial or test servers remain possible.

To keep only some commands from a class you otherwise want (e.g. a Scanning backend that only ever does ScanOnLine, not ScanOnCircle/ScanOnHelix), use register_subset() instead of hand-writing a matching unregister() call per command you don’t want - commands_of() answers “what would this class register” if you need that list for anything else:

server = IppDmeServer(command_classes=[register_server_class, register_dme_class])
register_subset(server.registry, register_scanning_class, keep={CommandName.SCAN_ON_LINE})

For a new command class (built-in or your own) where you want a method’s own parameters typed instead of a raw argument tuple, and its registered commands always kept truthfully in sync with what GetSupportedCommands() reports without a separate call, write it as a plain object with @command/@command_proprietary-decorated methods and pass it to register_object() instead; see pyippdme.server.dispatch.

Pass backend for the Scanning class’s real hardware control (see pyippdme.server.backend) - None (the default) is only a problem if a registered handler actually needs one and none was given. Pass csy_store to persist named coordinate systems across restarts, e.g. FileCsyStore(); see pyippdme.types.csy (the in-memory default does not). Pass machine_class to override the string every connection’s GetMachineClass() reports (6.4.1). Pass sample_surface to give PtMeas (6.12.1) a real synthetic part to measure against instead of always reporting exactly the commanded position; see pyippdme.server.surface. Pass state_factory if any registered command class needs more per-connection state than MachineState itself provides (see SimulationState for this library’s own bundled simulation’s extension) - it must build the same concrete type StateT this server is parameterized over. Pass network to listen somewhere other than TCP, e.g. a MemoryNetwork for connections that stay inside the process. Pass on_line_received/on_line_sent/on_connect/on_disconnect for observe-only wire-level visibility (e.g. ippdme serve --session-log); see pyippdme.protocol.hooks.

max_pending

How many acknowledged commands may wait for the one that runs; a further command is acknowledged only when there is room (5.4.3). None acknowledges at once.

network

Where this server’s listener (and anything a handler has to open) comes from.

sample_surface

The synthetic part PtMeas measures against, if any; see pyippdme.server.surface. None (the default) keeps PtMeas reporting the commanded position exactly.

raw_sensor

The simulated optical sensor behind DataAcquire; see RawSensor.

motion

What carries out a move; see MotionModel.

tool_handler

Tool change and qualification; see ToolHandler.

on_line_received

Observe-only wire-line hooks (see pyippdme.protocol.hooks), named from this server’s own point of view: on_line_received fires for a line a client sent it (a command), on_line_sent for a line it sent back (a response) - the mirror image of IppDmeClient’s hooks of the same name. Per 5.8, only one client is ever connected at a time, so unlike Spy’s hooks these carry no connection identifier to disambiguate.

on_connect

Called with the peer’s address (host:port) on each new connection/disconnection.

async start(host: str = '127.0.0.1', port: int = 0) → int

Bind and start accepting connections without blocking; return the bound port.

Unlike serve_forever() (which blocks the caller until cancelled), this returns as soon as the listening socket is up - for embedding the server in-process alongside other work in the same event loop (a REPL/TUI driving it directly, a test fixture, …) rather than running it as a standalone process. port=0 (the default) lets the network pick a free port, returned here so the caller can connect to it. Call close() when done.

property port: int | None

The port currently bound by start()/serve_forever(), or None.

property active_state: StateT | None

The state of the connected client, or None; only one is connected at a time (5.8).

async send_event(payload: NumericData | PropertyData | Items | StringValue | NameValue | Xml) → bool

Send an unsolicited event (tag E0000, 5.5.1) to the connected client.

Returns whether a client was connected. See pyippdme.server.builders for the pre-defined events of 5.5.3.

exception pyippdme.IppDmeServerError(error: ServerError)

A server reported an Error(...) response for a transaction.

Wraps pyippdme.protocol.errors.ServerError, which carries the F1/F2/F3/Text fields (5.6).

exception pyippdme.IppDmeTimeoutError

A transaction did not complete within the configured timeout.

class pyippdme.LoopThread(name: str = 'ippdme')

Run coroutines from any thread.

Used by ClientHost and ServerHost, and usable for your own hosts.

submit(coro: Coroutine[Any, Any, T]) → Future[T]

Start coro on the loop; the future gives its result or exception.

close() → None

Stop the loop and join its thread; nothing may be submitted afterwards.

class pyippdme.MachineBackend(*args, **kwargs)

Physical operations behind the Scanning command subset.

Every method is an async generator: implementations should yield each point as soon as it is actually acquired (matching 6.13.2’s “already measured data may be transmitted… while execution… is still in progress”), and return early - after any hardware-specific cleanup, e.g. stopping motion - once cancel is set.

class pyippdme.MachineState(session_active: bool = False, active_error: ServerError | None = None, homed: bool = False, home_position: tuple[float, float, float] | None=None, machine_class: str | tuple[str, ...]='CartCMM_TouchTrigger_Fixed_None_None_None_None', dme_version: str = '2.5', properties: dict[str, tuple[~pyippdme.protocol.ast.Number | ~pyippdme.protocol.ast.String | ~pyippdme.protocol.ast.NamedValue | ~pyippdme.protocol.ast.EventTag | ~pyippdme.protocol.ast.BasicName, ...]]=<factory>)

Per-connection state used by the mandatory Server/DME classes (6.3/6.4).

Deliberately minimal - just session lifecycle, error handling, machine identity, and the generic SetProp/GetProp fallback property store, since those are the only things pyippdme.server.classes (the two classes every conformant server needs, real or simulated) ever touch. A command class that needs more per-connection state than this - which is every other built-in class, all of them simulated - extends it by subclassing, e.g. SimulationState; IppDmeServer’s state_factory constructor argument is how a server is told to build that subclass instead of a plain MachineState. This keeps MachineState itself from growing a field per command class regardless of whether that class is even registered on a given server.

home_position: tuple[float, float, float] | None

Where Home() left the machine in the coordinates a client sees; None if the machine’s own home position applies (set by a motion model, see MotionModel.home).

properties: dict[str, tuple[Number | String | NamedValue | EventTag | BasicName, ...]]

Generic fallback store for SetProp/GetProp on properties not modeled individually by a built-in class, keyed by dotted property name.

carry_over_from(previous: MachineState) → None

Take over what the server keeps between clients (6.3.1: EndSession/StartSession).

The machine keeps being homed. A subclass adds the state of the command classes it owns: the active tool, the active coordinate system and the part.

class pyippdme.MemoryNetwork

Connections that stay inside the process: no sockets, no ports opened.

Each instance is its own isolated network. Ports are plain numbers scoped to the instance; hosts are ignored.

exception pyippdme.MotionError(severity: ErrorSeverity, number: str, cause: str, text: str, stopped_at: Vec3)

A move that ended early: the machine stands at stopped_at, not at the target.

class pyippdme.MotionModel(*args, **kwargs)

Carries out a move; returns the position the tool centre point ends at.

async probe(request: ProbeRequest) → ProbeResult

Search for the surface from the approach position; raise 1006 if none is found.

csy_context() → CsyContext | None

Return the coordinate system chain as this machine has it, or None for the default.

A model that knows more than the commands set (the angle of its rotary table for RotaryTableVarCsy) returns the complete context; the position a client reads is kept consistent through it when the client changes coordinate system.

async home(cancel: Event) → tuple[float, float, float] | None

Drive to the reference position for Home(); raise a ServerError if it cannot.

Returns where the machine stands afterwards in the coordinates a client sees (the active coordinate system), or None for the machine’s own home position.

class pyippdme.MotionRequest(cause: str, start: tuple[float, float, float], end: tuple[float, float, float], rotary_start: float, rotary_end: float, homed: bool, tool_name: str, cancel: Event)

One straight move of the tool centre point (and optionally the rotary table).

cause: str

The command that moves, e.g. GoTo or PtMeas.

tool_name: str

Name of the active tool, a key of the tool catalog.

cancel: Event

Set when the move must stop as soon as possible (AbortE()).

class pyippdme.Network(*args, **kwargs)

Opens outgoing and accepts incoming byte-stream connections.

async open_connection(host: str, port: int, *, limit: int = 65536) → tuple[StreamReaderLike, StreamWriterLike]

Connect to host:port; raise OSError if nothing is listening.

async start_server(on_client: Callable[[StreamReaderLike, StreamWriterLike], Awaitable[None]], host: str, port: int, *, limit: int = 65536) → Listener

Listen on host:port; port=0 picks a free one (see Listener.port).

class pyippdme.OffsetProvider(*args, **kwargs)

Optional part of a ToolHandler: the average tool offsets (Table 116).

Returns them in machine coordinates, or None to answer with zeros.

class pyippdme.ParameterName(*values)

Every atomic NamedValue/BasicName identifier a built-in class uses on the wire.

class pyippdme.PlaneSurface(point: tuple[float, float, float], normal: tuple[float, float, float])

An infinite flat plane through point, perpendicular to normal.

class pyippdme.ProbeRequest(cause: str, nominal: tuple[float, float, float], direction: tuple[float, float, float], approach: float, search: float, retract: float, speed: float, accel: float, tool_name: str, cancel: Event)

The probing cycle of PtMeas (6.12.1) from the approach position.

The machine stands at nominal + direction * approach; direction points from the surface towards the probe. approach is Part.Approach + Tool.Approach + AvrRadius (6.12.1): for a tool with a ball the tool centre point starts one radius further out. The search goes on until search beyond the nominal point, measured at the tip (so a ball centre travels approach - radius + search), and the machine retracts by retract (negative: back to the approach position) after the trigger.

speed: float

Speed and acceleration of the search (PtMeasPar).

class pyippdme.ProbeResult(contact: tuple[float, float, float], rest: tuple[float, float, float])

What the cycle found: the measured surface point and where the machine rests.

contact: tuple[float, float, float]

The measured point on the surface (compensated for the tip radius).

rest: tuple[float, float, float]

Tool centre point after the retract.

class pyippdme.RadiusProvider(*args, **kwargs)

Optional part of a ToolHandler: the average tip radius (AvrRadius, Table 106).

The approach position of PtMeas lies Part.Approach + Tool.Approach + AvrRadius from the nominal point (6.12.1), so a tool with a ball reports its radius here. Without it the radius is zero, as for optical tools.

class pyippdme.RawSensor(*args, **kwargs)

A simulated optical/laser sensor that answers DataAcquire (6.15.1).

Without one, DataAcquire synthesizes points from the requested positions alone. With one, the sensor decides what it sees: positions and directions are the control points the client sent (one per n; a single TCP position for n == 0), acquisition_type is SingleShot, MultiShot or Sweep. Return None to fall back to the built-in synthesis.

class pyippdme.SampleSurface(*args, **kwargs)

A synthetic surface a probing ray can intersect (structural - no inheritance needed).

direction need not be normalized. Returns the nearest intersection point with t >= 0 along direction from origin, or None if the ray never meets the surface (including when the surface is entirely behind origin). Implementations don’t need to know or care how far the caller intends to search - that bound is applied by the caller (pyippdme.simulation.classes.cartcmm_class), against Tool/Part’s Approach/Search properties.

exception pyippdme.ServerError(severity: ErrorSeverity, number: str, cause: str, text: str)

A parsed Error(F1, F2, F3, Text) response (5.6.3).

number: str

4-digit error number identifying the error, e.g. "1008".

Type:

F2

cause: str

name of the method that reported the error.

Type:

F3

text: str

Additional human-readable information.

class pyippdme.ServerHost

An asyncio loop on its own thread that serves one IppDmeServer.

A Qt (or any other) GUI keeps its main thread; the server, the motion model and the simulation run here. Use submit() to run a coroutine, e.g. the server’s key_press, from the GUI thread.

start(server: IppDmeServer[Any], host: str, port: int) → int

Listen on host:port (port=0 picks a free one); returns the bound port.

class pyippdme.SphereSurface(center: tuple[float, float, float], radius: float)

A sphere centered at center with the given radius (mm).

class pyippdme.Spy(host: str, port: int, *, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, intercept: ~collections.abc.Callable[[~pyippdme.spy.SpyMessage], ~collections.abc.Awaitable[bytes | ~collections.abc.Sequence[bytes] | None]] | None = None, on_message: ~collections.abc.Callable[[~pyippdme.spy.SpyMessage], None] | None = None, on_connect: ~collections.abc.Callable[[int, str], None] | None = None, on_disconnect: ~collections.abc.Callable[[int, str], None] | None = None)

Relay every byte between a client and the real server at host:port.

See the module docstring for what “unchanged” and “observe-only” mean here. Method names/shapes deliberately match IppDmeServer’s own (start()/ serve_forever()/close()/port), so embedding a spy alongside other asyncio work looks the same as embedding a server:

spy = Spy("192.168.1.50", 1294, on_message=lambda m: print(m))
port = await spy.start("127.0.0.1", 0)
...
await spy.close()
async start(host: str = '127.0.0.1', port: int = 0) → int

Bind and start accepting connections without blocking; return the bound port.

port=0 lets the OS pick a free port, returned here so the caller can connect to it (embedding a spy in a test, say). Call close() when done.

property port: int | None

The port currently bound by start()/serve_forever(), or None.

class pyippdme.SpyDirection(*values)

Which way a relayed message travelled.

class pyippdme.SpyMessage(connection_id: int, direction: SpyDirection, timestamp: datetime, line: bytes, forwarded: tuple[bytes, ...] | None = None)

One line received by Spy (including its trailing \r\n).

line is the line as it arrived. forwarded is what was sent on in its place: None if it was forwarded unchanged, otherwise the lines an intercept function returned (empty if the message was dropped).

class pyippdme.ToolHandler(*args, **kwargs)

The physical side of changing and qualifying tools.

Without one, ChangeTool and ReQualify take no time and always succeed. A handler can animate the trip to the tool rack, refuse while the machine is not ready, or find the reference sphere for ReQualify; raise a ServerError to fail the command.

alignment_volume(tool_name: str) → tuple[tuple[float, float, float], float] | None

Return the sphere the tool occupies while aligned (Tool.AlignmentVolume, Fig. 52/53).

(centre, radius): the vector from the tool’s reference point to the sphere centre, in machine coordinates, and the radius. None if the tool has no such volume.

collision_volume(tool_name: str) → list[Obb] | None

Oriented bounding boxes covering the tool (Tool.CollisionVolume, Figures 49-51).

Centres relative to the tool’s reference point and axes, in machine coordinates. None if the tool has no such volume.

class pyippdme.VirtualCMM(*, backend: ~pyippdme.server.backend.MachineBackend | None = None, csy_store: ~pyippdme.types.csy.CsyStore | None = None, machine_class: str | None = None, command_classes: ~collections.abc.Sequence[~collections.abc.Callable[[~pyippdme.server.registry.CommandRegistry], None]] = (<function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>), network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, sample_surface: ~pyippdme.server.surface.SampleSurface | None = None, raw_sensor: ~pyippdme.server.surface.RawSensor | None = None, motion: ~pyippdme.server.motion.MotionModel | None = None, tool_handler: ~pyippdme.server.motion.ToolHandler | None = None, on_line_received: ~collections.abc.Callable[[str], None] | None = None, on_line_sent: ~collections.abc.Callable[[str], None] | None = None, on_connect: ~collections.abc.Callable[[str], None] | None = None, on_disconnect: ~collections.abc.Callable[[str], None] | None = None, max_pending: int | None = None)

A fully simulated CMM, ready to serve_forever() with no further setup.

import asyncio
from pyippdme.simulation.virtual_cmm import VirtualCMM

asyncio.run(VirtualCMM().serve_forever(host="127.0.0.1"))
async key_press(key: str) → bool

Press a key on the virtual jog box; the client gets KeyPress(key).

The event is sent only while the user is enabled (5.5.3); returns whether it was sent.

async clearance_point(x: float, y: float, z: float) → bool

Set a clearance point by hand: the machine moves there; the client gets GoTo(...).

async manual_point(x: float, y: float, z: float, ijk: tuple[float, float, float] = (0.0, 0.0, 0.0)) → bool

Pick a point by hand: the client gets PtMeas(...) with the report fields.

async change_tool(tool_name: str) → bool

Change the tool at the machine: the client gets ChangeTool(ToolName) (5.5.3).

async data_acquire(acq_name: str, acquisition_type: str, settings_name: str, points: Sequence[tuple[tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]]] = ()) → bool

Take a measurement at the machine: the client gets DataAcquire(...) (6.15).

Like the other unsolicited events it is sent only while the user is enabled.

async open_tool_collection(path: str) → bool

Open a tool collection at the machine: the client gets OpenToolCollection(path).

async set_property(name: str, *values: float | str) → bool

Change a property at the machine: the client gets SetProp(name(values)) (5.5.3).

pyippdme.command(name: Literal[CommandName.GET_DME_VERSION]) → Callable[[Callable[[Any, CommandContext[Any]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[Any, CommandContext[Any]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]
pyippdme.command(name: Literal[CommandName.SCAN_ON_LINE]) → Callable[[Callable[[Any, CommandContext[Any], float, float, float, float, float, float, float, float, float, float, bool | None], AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml]]], Callable[[Any, CommandContext[Any], float, float, float, float, float, float, float, float, float, float, bool | None], AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml]]]
pyippdme.command(name: Literal[CommandName.SCAN_UNKNOWN_DENSITY]) → Callable[[Callable[[Any, CommandContext[Any], float | None, float | None, float | None], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[Any, CommandContext[Any], float | None, float | None, float | None], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]
pyippdme.command(name: CommandName) → Callable[[Callable[[Any, CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[Any, CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]
pyippdme.command(name: str, *, arguments: tuple[Parameter, ...]) → Callable[[Callable[[Any, CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[Any, CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]

Mark a method as the handler for name; register_object() finds it later.

See the module docstring for the rule on arguments: never given for a standard CommandName (derived automatically instead), always required otherwise. The specific overloads above are the only reason to prefer this over command() directly - they pin a handful of standard commands’ expected parameter types statically; this implementation’s own signature is deliberately untyped (Any), since it is never what a caller’s type checker actually sees - only the overloads above are, which is where the real guarantee comes from.

pyippdme.command_proprietary(namespace: str, name: str, *, arguments: tuple[Parameter, ...]) → Callable[[Callable[[Any, CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[Any, CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]

Mark a method as the handler for a proprietary command (6.1).

arguments is required - a proprietary command’s shape is entirely your own, there is nothing to derive it from.

pyippdme.commands_of(register_fn: Callable[[CommandRegistry], None]) → tuple[str, ...]

Return the command names register_fn would register, without a real registry.

There is no separate, hand-maintained list of “Scanning’s commands” (or any other class’s) anywhere - a register_*_class function’s own body is that list, so this reads it from the one place it can’t drift out of sync: by actually calling it against a scratch registry.

pyippdme.component_name(register_fn: Callable[[CommandRegistry], None]) → str

Return the short name a register_*_class function stands for, e.g. "cartcmm".

Read from the module register_fn is defined in (pyippdme.simulation.classes.cartcmm_class -> "cartcmm"), not its __name__ - every one of these functions is named plainly register in its own module and only gets an alias like register_cartcmm_class when re-exported from pyippdme.server.classes/pyippdme.simulation.classes, and __name__ doesn’t follow that alias. Used wherever a caller needs to refer to “which command classes” by name (CLI flags, a machine-class string derived from them) without a second, hand-maintained name-to-function table that could drift from what it actually names.

pyippdme.proprietary_name(namespace: str, name: str) → str

Build a spec-compliant proprietary command/property/parameter name.

namespace must be exactly two letters (6.1: “a company specific abbreviation having two characters”); name is the part specific to your extension, e.g. proprietary_name("XX", "ProprietaryCommandName") -> "XXProprietaryCommandName".

pyippdme.register_object(registry: CommandRegistry, obj: object) → None

Register every @command/@command_proprietary-marked method found on obj.

GetSupportedCommands()/GetSupportedArguments() (6.4.1) reflect exactly what this registers - there is no separate capability declaration anywhere else to keep in sync (see the module docstring). A typed method’s parameters are checked against its own declared schema immediately, so a mismatch fails at server startup, not at a client’s first call.

pyippdme.register_subset(registry: CommandRegistry, register_fn: Callable[[CommandRegistry], None], keep: Iterable[str]) → None

Register everything register_fn defines, then drop whatever isn’t in keep.

For picking which commands within one command class a particular server instance actually supports (e.g. a vision-only Scanning backend that does ScanOnLine but not ScanOnCircle/ScanOnHelix) - IppDmeServer’s own command_classes parameter already covers picking whole classes; this is the same idea one level finer, without hand-writing a matching CommandRegistry.unregister() call per command you don’t want. GetSupportedCommands()/ GetSupportedArguments() (6.4.1) reflect the result correctly, since they read the registry directly - nothing dropped here is ever registered in the first place from a caller’s perspective.

Commands register_fn would have registered anyway (because keep included them, or because they were already present before this call) are left untouched either way.

A typed, high-level client on top of IppDmeClient.

IppDmeClient is a thin protocol client: call("GoTo", NamedValue(...)) returns a raw tuple of DataPayload nodes, and the caller is responsible for knowing the wire shape of every command by hand. IppDmeMachine wraps it with typed Python methods and dataclass/tuple return values instead, one namespace per top-level object of the standard’s own object model (the same one GetMachineClass()’s Server_Tool_Alignment_Mover_ToolChanger_Part_RotaryTable naming scheme enumerates, 6.4.1) - IppDmeMachine.server, .dme, .cart_cmm, .tool, .found_tool, .tool_changer, .scanning, .form_tester, .mover, .rotary_table, .part, .raw_data, mirroring how the server side already exposes that same object model as a set of command classes (pyippdme.server.classes).

Anything the namespaces do not wrap stays reachable with machine.client.call(...), for example proprietary commands.

Every method here is a thin encode/decode layer over IppDmeClient.call(); none of it changes wire behaviour.

class pyippdme.client.model.Server(client: IppDmeClient)

The Server class (6.3): session/error status.

Beyond what IppDmeClient already covers directly.

abort_e() → None

Abort everything currently executing or queued (5.7).

get_prop(name: str) → float | str | tuple[float, ...] | None

Read one property by its dotted name, e.g. "Part.Temperature" (6.3.1.1).

The value is a number, a string, or a tuple of numbers for a property such as "Tool.Alignment".

get_props(*names: str) → Report

Read several properties with one GetProp (6.3.1.1).

get_prop_e(name: str) → float | str | tuple[float, ...] | None

Like get_prop(), but as a prioritized command that bypasses the queue (5.7).

get_props_e(*names: str) → Report

Like get_props(), but as a prioritized command that bypasses the queue (5.7).

set_prop(name: str, value: float | str | Sequence[float]) → None

Write one property by its dotted name (6.3.1.1).

set_props(values: Mapping[str, float | str | Sequence[float]]) → None

Write several properties with one SetProp (6.3.1.1).

unsolicited_events() → AsyncIterator[DataResponse]

Iterate the events the server sends on its own with tag E0000 (5.5.1), raw.

async events() → AsyncIterator[KeyPress | ClearancePoint | ManualPoint | ToolChanged | PropertyChanged | ToolCollectionOpened | DataAcquireRequested | UnknownEvent]

Iterate the events the server sends on its own, as the pre-defined ones of 5.5.3.

KeyPress, GoTo, PtMeas, ChangeTool, SetProp and OpenToolCollection become pyippdme.client.events objects; any other event comes as UnknownEvent.

clear_all_errors() → None

Let the server recover from an error (5.6).

get_xtd_err_status() → Report

Query the extended error status (6.3.1): all status lines merged by name.

For example IsHomed, plus ActiveError and Severity while an error is active.

enum_name_spaces() → tuple[str, ...]

List the proprietary namespaces the server uses, if any (6.3.1).

stop_daemon(event_tag: EventTag) → None

Stop the daemon that was started with event_tag (5.5.2).

enum_prop(reference: str) → tuple[tuple[str, str], ...]

List the direct children of reference (e.g. "Tool.GoToPar", "Part").

Returns ((child_name, kind), ...) in server order (a plain dict would silently collapse the repeated names enum_all_prop() can return at different tree positions, e.g. every parameter’s own Min); kind is one of "Number", "String", or "Property" (Table 20).

enum_all_prop(reference: str) → tuple[tuple[str, str], ...]

Like enum_prop(), but recursing into every "Property"-typed child.

class pyippdme.client.model.Dme(client: IppDmeClient)

The DME class (6.4), mandatory for every conformant server.

get_machine_class() → str

Return the machine class; use get_machine_classes() if the server has several.

get_machine_classes() → tuple[str, ...]

Return every machine class the server implements (Table 25).

class pyippdme.client.model.TemperatureSensorInfo(name: str, kind: str, cmm_temp_correction: bool, scale_axis: str | None)

One GetTemperatureSensors() entry (Table 43).

kind: str

One of "Mover", "Part", "CMM".

scale_axis: str | None

The axis this sensor measures, for "Mover"-kind sensors only.

class pyippdme.client.model.CartCmm(client: IppDmeClient)

A subset of the CartCMM/Cartesian/TouchTrigger classes (6.5, 6.8, 6.12).

on_pt_meas_report(*names: str) → None

Choose which values pt_meas reports, e.g. "X", "Y", "Z", "IJK" (6.12.1).

pt_meas_self_center(x: float | None = None, y: float | None = None, z: float | None = None, ijk: tuple[float, float, float] | None = None) → Report

Measure a point with self-centering (6.14).

pt_meas_self_center_locked(x: float | None = None, y: float | None = None, z: float | None = None, ijk: tuple[float, float, float] | None = None, lmn: tuple[float, float, float] | None = None) → Report

Measure a point with self-centering inside the plane normal to lmn (6.14).

get(*axes: str) → Report

Query one or more axes or properties, e.g. await cart_cmm.get("X", "IJK", "R").

go_to(x: float | None = None, y: float | None = None, z: float | None = None, *, r: float | None = None, a: float | None = None, b: float | None = None, c: float | None = None, alignment: ToolAlignment | None = None, sync: bool | None = None) → None

Move to an absolute position (6.8.1).

r is the rotary table angle, a, b and c are tool angles and alignment the tool orientation. With sync=True all axes start and end together.

step(x: float | None = None, y: float | None = None, z: float | None = None, *, r: float | None = None, a: float | None = None, b: float | None = None, c: float | None = None, sync: bool | None = None) → None

Perform a relative move (6.8.1): add to the current position, not replace it.

pt_meas(x: float | None = None, y: float | None = None, z: float | None = None, *, ijk: tuple[float, float, float] | None = None, r: float | None = None, a: float | None = None, b: float | None = None, c: float | None = None, alignment: ToolAlignment | None = None, align_part: PartAlignment | None = None) → Report

Measure a point (6.12.1); ijk is the probing direction.

The result holds what on_pt_meas_report() asked for.

read_all_temperatures() → dict[str, float]

Every currently-connected sensor’s reading; a disconnected sensor is omitted.

class pyippdme.client.model.ToolParameterValue(minimum: float, maximum: float, default: float, act: float)

One parameter’s Min/Max/Def/Act quadruplet (6.10.4), as read over the wire.

class pyippdme.client.model.OrientedBox(center: tuple[float, float, float], extension: tuple[float, float, float], i: tuple[float, float, float], j: tuple[float, float, float], k: tuple[float, float, float])

One oriented bounding box of Tool.CollisionVolume() (Table 117).

class pyippdme.client.model.AlignmentSphere(center: tuple[float, float, float], radius: float)

One sphere of Tool.AlignmentVolume() (Table 118).

class pyippdme.client.model.FoundTool(client: IppDmeClient)

The FoundTool object (6.22): the tool the last find_tool located.

class pyippdme.client.model.Tool(client: IppDmeClient)

A subset of the Tool class (6.10): its properties, parameter blocks and alignment.

re_qualify() → None

Requalify the active tool (6.10.2).

align_tool(primary: tuple[float, float, float], alpha: float, secondary: tuple[float, float, float] | None = None, beta: float | None = None) → None

Align the tool (6.20); secondary and beta must be given together.

calc_tool_alignment(axis: str = 'A', *, namespace: str = 'Tool') → tuple[float, ...]

Calculate the alignment vector(s) for the current tool angles (6.20).

calc_tool_angles(primary: tuple[float, float, float], secondary: tuple[float, float, float] | None = None, *, namespace: str = 'Tool') → dict[str, float]

Calculate the tool angles (A, B, maybe C) for alignment vector(s) (6.20).

avr_radius() → float

Average effective radius of the tool tip (6.20.1).

pointer() → str

Return the name of the active tool, which can be "NoTool" (Table 64).

go_to_par() → str

Return the pointer to the GoToPar parameter block (6.10.4).

pt_meas_par() → str

Return the pointer to the PtMeasPar parameter block (Table 77).

scan_par() → str

Return the pointer to the ScanPar parameter block (6.13.2).

opt_par() → str

Return the pointer to the OptPar parameter block of an optical tool (6.10.4).

get_parameter(block: str, name: str) → ToolParameterValue

E.g. await tool.get_parameter("PtMeasPar", "Retract").

class pyippdme.client.model.Scanning(client: IppDmeClient, point_format: _PointFormat[PointT])

The Scanning class (6.13).

machine.scanning yields each scanned point as (x, y, z). reporting() gives the same commands with other reported values per point.

reporting(*names: str, widths: Mapping[str, int] | None = None) → Scanning[Report]

Return the scan commands with each point as a Report of names.

names are what OnScanReport asks for, for example "X", "Y", "Z", "Q" or "IJK". widths gives how many numbers a name contributes to a point when the standard does not fix it, for example {"Tool.Alignment": 6} or a proprietary value.

on_scan_report(*names: str) → None

Choose which values a scan reports (6.13.2).

The scan methods set their own format before each scan; this is for scans started some other way.

scan_on_line(start: tuple[float, float, float], end: tuple[float, float, float], direction: tuple[float, float, float], step_width: float, rotary_table: bool | None = None) → AsyncIterator[PointT]

Scan a straight line, yielding each measured point as it arrives (6.13.2.1).

scan_on_circle(center: tuple[float, float, float], start: tuple[float, float, float], normal: tuple[float, float, float], delta: float, surface_angle: float, step_width: float, rotary_table: bool | None = None) → AsyncIterator[PointT]

Scan a circular arc of delta degrees around center (6.13.2.1).

scan_on_helix(center: tuple[float, float, float], start: tuple[float, float, float], normal: tuple[float, float, float], delta: float, surface_angle: float, step_width: float, pitch: float, rotary_table: bool | None = None) → AsyncIterator[PointT]

Scan a helix: a circular arc that also rises by pitch per turn (6.13.2.1).

scan_on_curve(points: Sequence[CurvePoint], *, closed: bool = False, rotary_table: bool | None = None) → AsyncIterator[PointT]

Scan a client-supplied nominal curve, yielding each measured point (6.13.2.1).

The optional tool directions and rotary-table angle of CurvePoint are sent as extra columns when the points have them.

scan_in_plane_end_is_sphere(start: tuple[float, float, float], start_ijk: tuple[float, float, float], plane_normal: tuple[float, float, float], direction_point: tuple[float, float, float], step_width: float, end_center: tuple[float, float, float], diameter: float, n: int, end_ijk: tuple[float, float, float]) → AsyncIterator[PointT]

Scan an unknown contour in a plane until n hits of the end sphere (6.13.2.2).

scan_in_plane_end_is_plane(start: tuple[float, float, float], start_ijk: tuple[float, float, float], plane_normal: tuple[float, float, float], direction_point: tuple[float, float, float], step_width: float, end_plane_point: tuple[float, float, float], end_plane_normal: tuple[float, float, float], n: int, end_ijk: tuple[float, float, float]) → AsyncIterator[PointT]

Scan an unknown contour in a plane until n crossings of the end plane (6.13.2.2).

scan_in_plane_end_is_cyl(start: tuple[float, float, float], start_ijk: tuple[float, float, float], plane_normal: tuple[float, float, float], direction_point: tuple[float, float, float], step_width: float, axis_point: tuple[float, float, float], axis_direction: tuple[float, float, float], diameter: float, n: int, end_ijk: tuple[float, float, float]) → AsyncIterator[PointT]

Scan an unknown contour in a plane until n hits of the end cylinder (6.13.2.2).

scan_in_cyl_end_is_sphere(axis_point: tuple[float, float, float], axis_direction: tuple[float, float, float], start: tuple[float, float, float], start_ijk: tuple[float, float, float], direction_point: tuple[float, float, float], step_width: float, end_center: tuple[float, float, float], diameter: float, n: int, end_ijk: tuple[float, float, float]) → AsyncIterator[PointT]

Scan an unknown contour on a cylinder until n hits of the end sphere (6.13.2.2).

scan_in_cyl_end_is_plane(axis_point: tuple[float, float, float], axis_direction: tuple[float, float, float], start: tuple[float, float, float], start_ijk: tuple[float, float, float], direction_point: tuple[float, float, float], step_width: float, end_plane_point: tuple[float, float, float], end_plane_normal: tuple[float, float, float], n: int, end_ijk: tuple[float, float, float]) → AsyncIterator[PointT]

Scan an unknown contour on a cylinder until n end-plane crossings (6.13.2.2).

class pyippdme.client.model.FormTester(client: IppDmeClient)

A subset of the FormTester class (6.6.1).

class pyippdme.client.model.Mover(client: IppDmeClient)

The Mover class (6.7.1).

on_move_report(time: float, dis: float, *axes: str, prioritized: bool = False) → Transaction

Start the move-report daemon (6.10.2); reports arrive via Transaction.events().

Stop it with machine.server.stop_daemon(transaction.tag).

class pyippdme.client.model.ToolChanger(client: IppDmeClient)

The ToolChanger class (6.22), over a small fixed tool catalog.

See pyippdme.simulation.classes.tool_class.TOOL_CATALOG for which tool names the built-in/VirtualCMM server accepts.

enum_tool_collection(node_name: str) → tuple[tuple[str, str], ...]

List the direct children of a tool collection as (name, kind) pairs (6.22).

enum_all_tool_collections(node_name: str) → tuple[tuple[str, str], ...]

Like enum_tool_collection(), but recursing into sub-collections (6.22).

get_change_tool_action(tool_name: str) → tuple[str, tuple[float, float, float]]

Return (action, (dx, dy, dz)).

action is one of “Switch”/”Rotate”/”MoveAuto”/”MoveMan” (6.22.1’s GetChangeToolAction table).

class pyippdme.client.model.Part(client: IppDmeClient)

The Part class (6.24.2): temperature/approach/search/retract properties.

class pyippdme.client.model.RotaryTable(client: IppDmeClient)

A subset of the RotaryTable class (6.23).

align_part(part_vector: tuple[float, float, float], machine_vector: tuple[float, float, float], alpha: float, *, second_part_vector: tuple[float, float, float] | None = None, second_machine_vector: tuple[float, float, float] | None = None, beta: float | None = None) → tuple[tuple[float, float, float], ...]

Orient the part (6.23.1); the second vectors and beta are for a second table.

Returns the vectors that were reached: two per rotary table.

class pyippdme.client.model.RawDataHandling(client: IppDmeClient)

A subset of the Optical/RawDataHandling classes (6.15, 6.17).

raw_data_bin_setup(data_format: str, port: int, live_mode: bool = False) → None

Choose the sample format ("float"/"double") and port to send to (6.17.2.1).

get_raw_data_bin(acq_name: str) → None

Send an acquisition to the port chosen with raw_data_bin_setup() (6.17.2.1).

The samples do not come back through this connection: read them from the port, for example with pyippdme.rawdata.transfer.read_samples().

data_acquire(acq_name: str, acquisition_type: str, settings_name: str, points: Sequence[AcquisitionPoint] = (), *, step_width: float | None = None, rotary_table: bool | None = None) → None

Trigger an acquisition (6.15.1).

Without points this is a single shot at the current position. Otherwise points are the positions and tool orientations the sensor moves along; step_width is the maximum step of a multi-shot or sweep, and rotary_table lets the server move the rotary table (it needs step_width).

get_raw_data_file(acq_name: str) → str

Return the file:// URL the acquisition’s data was written to.

get_raw_data_sha_mem(acq_name: str) → tuple[str, int, int]

Return (shared_memory_name, offset, size_bytes).

class pyippdme.client.model.FeatureExtraction(client: IppDmeClient)

The deprecated FeatureExtraction class (Annex J.2).

roi(name: str, shape: Shape, *, include: bool = True) → None

Define a region of interest that feature_extract can refer to by name.

feature_extract(acquisitions: Sequence[str], feature: Shape, rois: Sequence[str], settings_name: str) → tuple[Report, ...]

Extract the geometric element feature from the acquisitions.

feature_extract_points(acquisitions: Sequence[str], feature: Shape, rois: Sequence[str], settings_name: str, step_width: float) → AsyncIterator[tuple[float, ...]]

Extract the qualified edge points at step_width, in the OnScanReport order.

class pyippdme.client.model.IppDmeMachine(client: IppDmeClient)

A typed facade over one IppDmeClient connection.

Groups commands the same way the standard’s own object model does (one namespace per top-level object), so callers work with typed methods and values instead of building/decoding raw pyippdme.protocol.ast nodes by hand:

machine = await IppDmeMachine.connect(host, port)
await machine.start_session()
await machine.cart_cmm.go_to(x=10, y=20)
position = await machine.cart_cmm.get_position()

Anything not wrapped by a namespace here remains reachable via client directly (machine.client.call(...)).

async classmethod connect(host: str, port: int, *, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, on_line_sent: ~collections.abc.Callable[[str], None] | None = None, on_line_received: ~collections.abc.Callable[[str], None] | None = None) → IppDmeMachine

Connect and wrap the result.

network, on_line_sent and on_line_received are as in connect().

async start_session() → None

Shortcut for machine.server.start_session().

async end_session() → None

Shortcut for machine.server.end_session().

The decoded form of a response made of named values such as X(1),Y(2),IJK(0,0,1).

pyippdme.client.report.ReportValue = float | str | tuple[float, ...] | None

None stands for the NULL a server reports for information it cannot deliver (6.10.2).

class pyippdme.client.report.Report(values: Mapping[str, float | str | tuple[float, ...] | None])

Named values by name: a single number is a float, several numbers are a tuple.

A report compares equal to a plain dict with the same content:

report = await machine.cart_cmm.pt_meas(x=1, y=2, z=3, ijk=(0, 0, 1))
report.number("X")     # 1.0
report.vector("IJK")   # (0.0, 0.0, 1.0)
number(name: str) → float

Return name as a single number.

vector(name: str) → tuple[float, ...]

Return name as a tuple of numbers, also when it holds only one.

text(name: str) → str

Return name as a string.

pyippdme.client.report.report_from_payload(payload: NumericData | PropertyData | Items | StringValue | NameValue | Xml) → Report

Decode an Items response into a Report.

The features and regions of interest of the legacy FeatureExtraction class (Annex J.2).

class pyippdme.client.features.Shape(*args, **kwargs)

Something that is sent as one named argument, such as Circle(...).

to_argument() → NamedValue

Return the shape as the argument it is sent as.

class pyippdme.client.features.CylinderShape(position: tuple[float, float, float], normal: tuple[float, float, float], orientation: tuple[float, float, float], radius: float, height: float)

Cylinder(x,y,z,i,j,k,l,m,n,r,h): a feature to extract or a region of interest.

class pyippdme.client.features.CircleShape(position: tuple[float, float, float], normal: tuple[float, float, float], orientation: tuple[float, float, float], radius: float)

Circle(x,y,z,i,j,k,l,m,n,r): a feature to extract or a region of interest.

class pyippdme.client.features.LineShape(position: tuple[float, float, float], direction: tuple[float, float, float], length: float)

Line(x,y,z,i,j,k,l): a feature to extract or a region of interest.

class pyippdme.client.features.PointShape(position: tuple[float, float, float], normal: tuple[float, float, float])

Point(x,y,z,i,j,k): a feature to extract.

class pyippdme.client.features.SphereShape(position: tuple[float, float, float], normal: tuple[float, float, float], orientation: tuple[float, float, float], radius: float)

Sphere(x,y,z,i,j,k,l,m,n,r): a region of interest.

class pyippdme.client.features.CircleRel(dr: float)

CircleRel(dr): a region around a circle feature, wider by dr.

class pyippdme.client.features.CylinderRel(dr: float, dh: float)

CylinderRel(dr,dh): a region around a cylinder feature, larger by dr and dh.

class pyippdme.client.features.SphereRel(dr: float)

SphereRel(dr): a region around a sphere feature, wider by dr.

class pyippdme.client.features.Polygon2D(points: Sequence[tuple[float, float, float]])

Polygon2D(x1,y1,z1,...,xn,yn,zn): a closed polygon without loops.

class pyippdme.client.features.Polygon3D(points: Sequence[tuple[float, float, float]])

Polygon3D(x1,y1,z1,...,xn,yn,zn): a closed polygon without loops.

pyippdme.client.features.roi(name: str, shape: Shape, include: bool) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build ROI’s argument list.

pyippdme.client.features.feature_extract(acquisitions: Sequence[str], feature: Shape, rois: Sequence[str], settings_name: str, step_width: float | None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build FeatureExtract’s argument list.

Without step_width the report is the geometric element (GeoElem()), otherwise the qualified edge points at that step width (QEPs(S(...))).

The events a server sends on its own with tag E0000 (5.5.1, 5.5.3).

class pyippdme.client.events.KeyPress(key: str)

KeyPress(NameOfKey): a key was pressed on the jog box.

Besides the keys of the machine, Done, Del and the soft keys F1 … Fn are defined.

class pyippdme.client.events.ClearancePoint(values: Report)

GoTo(...): the user set a clearance or intermediate point.

values are the fields of OnPtMeasReport; vectors are (0, 0, 0).

class pyippdme.client.events.ManualPoint(values: Report)

PtMeas(...): the user picked a point by hand; values as of OnPtMeasReport.

class pyippdme.client.events.ToolChanged(tool_name: str)

ChangeTool(ToolName): the tool was changed without a command from the client.

class pyippdme.client.events.PropertyChanged(name: str, value: float | str | tuple[float, ...] | None)

SetProp(...): a property was changed without a command from the client.

class pyippdme.client.events.ToolCollectionOpened(path: str)

OpenToolCollection(ToolCollectionPath): the server changed the tool collection.

class pyippdme.client.events.DataAcquireRequested(acq_name: str, acquisition_type: str, settings_name: str, positions: tuple[tuple[tuple[float, ...], tuple[float, ...], tuple[float, ...]], ...], step_width: float | None = None, rotary_table: bool | None = None)

DataAcquire(...): the user took a measurement at the machine (6.15, use case 2).

The client usually inserts the command into its inspection plan. positions are the (position, primary, secondary) triples; step_width and rotary_table are the optional last numbers when the server sent them.

class pyippdme.client.events.UnknownEvent(payload: NumericData | PropertyData | Items | StringValue | NameValue | Xml)

An event the standard does not define, for example a proprietary one.

pyippdme.client.events.parse_event(response: DataResponse) → KeyPress | ClearancePoint | ManualPoint | ToolChanged | PropertyChanged | ToolCollectionOpened | DataAcquireRequested | UnknownEvent

Read the pre-defined event (5.5.3) a data response with tag E0000 carries.

Handles for the commands the object model sends: await the result, or check the Ack first.

A method of IppDmeMachine starts its command as soon as it is called and returns a Call (or, for a command that streams data, a StreamCall):

await machine.cart_cmm.go_to(x=10)             # waits until the command is done

call = machine.cart_cmm.pt_meas(x=1, y=2, z=3)  # command sent
await call.acknowledged()                       # the server accepted it
position = await call                           # the typed result

An Ack only means the server received the command. A command that then fails (an unsupported command, a bad argument, no session, …) is reported after the Ack, so it raises IppDmeServerError when the call is awaited, not from Call.acknowledged().

pyippdme.client.call.record_transaction(transaction: Transaction) → None

Hand a command the client just sent to the handle that started it, if any.

pyippdme.client.call.unrecorded() → Iterator[None]

Keep commands sent inside the block (a method’s setup step) out of its handle’s Ack.

class pyippdme.client.call.Call(coroutine: Coroutine[Any, Any, T])

A command that has been sent; await it for its result.

class pyippdme.client.call.StreamCall(source: AsyncIterator[T])

A command that streams data; iterate it with async for.

pyippdme.client.call.call_handle(func: Callable[[P], Coroutine[Any, Any, T]]) → Callable[[P], Call[T]]

Make a coroutine function start its command when called and return a Call.

pyippdme.client.call.stream_handle(func: Callable[[P], AsyncIterator[T]]) → Callable[[P], StreamCall[T]]

Make an async generator function start its command when called, returning a StreamCall.

Async I++ DME client (section 5).

class pyippdme.client.IppDmeClient(transport: LineTransport, *, on_line_sent: Callable[[str], None] | None = None, on_line_received: Callable[[str], None] | None = None)

A connection to an I++ DME server.

Use connect() to open a connection; the client then reads responses in a background task and routes them to the Transaction returned by send(), or to unsolicited_events() for E0000 events (5.5.1).

allocate_event_tag() → EventTag

Reserve the next free EventTag.

For a caller that needs to send() a daemon-starting command itself (see start_daemon() for the common case that just wants one and doesn’t care which); public because knowing which commands start a daemon is protocol/library knowledge this class doesn’t have (see pyippdme.client.interaction, which does).

send(name: str, *args: Number | String | NamedValue | EventTag | BasicName, tag: Tag | EventTag | None = None) → Transaction

Send a command and return a Transaction to await responses on.

Pass an explicit tag (an EventTag) to start a daemon whose events should be consumed via Transaction.events() after the initial transaction completes.

async call(name: str, *args: Number | String | NamedValue | EventTag | BasicName) → tuple[NumericData | PropertyData | Items | StringValue | NameValue | Xml, ...]

Send a command and wait for it to complete, returning its data.

Commands wait for the Ack of the one before them (5.4.3), so calls made at the same time are sent one after another.

async call_streaming(name: str, *args: Number | String | NamedValue | EventTag | BasicName) → AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml]

Send a command and yield its data responses as they arrive.

Unlike call(), which waits for the whole transaction to finish and returns everything at once, this is for handlers that stream results incrementally (e.g. ScanOnLine); see stream().

async start_daemon(name: str, *args: Number | String | NamedValue | EventTag | BasicName) → Transaction

Send an event-tagged command that starts a daemon (5.5.2).

unsolicited_events() → AsyncIterator[DataResponse]

Iterate unsolicited server events (tag E0000, 5.5.1).

Names of the commands this library’s built-in command classes register.

Every registry.register("GoTo", ...)-style call in pyippdme.server.classes uses a member of CommandName instead of a bare string literal, and a caller of the low-level IppDmeClient API can do the same - client.call(CommandName.GO_TO, ...) instead of retyping "GoTo" by hand, with a typo caught as an unknown name (by mypy/the IDE) rather than surfacing later as a wire-level 0501 Unsupported command. CommandName is a StrEnum, so it is a plain string everywhere one is expected - passing a member to call() or comparing it against wire text both work exactly as if it were the string itself.

This only covers the built-in classes’ own commands (see pyippdme.server.classes); a proprietary command registered via command_proprietary() has no member here; naming it well (and, ideally, exporting a constant for it too) is the caller’s own responsibility.

class pyippdme.protocol.commands.CommandName(*values)

Every command name a built-in command class registers, grouped by class.

pyippdme.protocol.commands.PROPERTY_NAMES = frozenset({'A', 'AlignMode', 'Alignment', 'AlignmentVolume', 'Approach', 'AvrOffsets', 'B', 'C', 'Collection', 'CollisionVolume', 'ER', 'IJK', 'IJKAct', 'Id', 'LastQualified', 'Name', 'Q', 'R', 'Retract', 'Search', 'Temperature', 'X', 'XpanCoefficient', 'Y', 'Z'})

Properties and report fields the standard defines (6.3.1.1, 6.5.2, 6.10, 6.20-6.24). They are only valid as an argument of another command; sent as a command of their own, the server answers error 0508 “Bad context”, not 0501 “Unsupported command”.

Names this library’s built-in command classes use as NamedValue/BasicName wire text.

Where CommandName names the method half of a wire line (GoTo(...)), ParameterName names the argument/response identifiers that appear inside the parentheses - X in GoTo(X(10)), Center/IJK in GoToOnCircle(Center(...), IJK(...), ...), and so on - so a caller building a request by hand (via the low-level IppDmeClient API, NamedValue(ParameterName.X, ...) instead of NamedValue("X", ...)) or reading a response has the same typo-safety CommandName already gives command names. ParameterName is a StrEnum, so a member is a plain string everywhere one is expected.

This only covers atomic identifiers: a single NamedValue/BasicName literal this library’s built-in classes construct or parse verbatim, such as X/Center/Format. It deliberately does not cover:

  • Purely positional arguments (e.g. ScanOnLine’s Sx, Sy, Sz, ...), since those names never appear as wire text at all - only as descriptive labels in Parameter for GetSupportedArguments.

  • Enum/name-kind top-level Parameter names like GoTo’s Positions or EnumProp’s Reference, which are also GetSupportedArguments schema labels only - the wire text a caller actually sends is the enum’s members (X(), Y(), …), which are covered here, or an arbitrary caller-supplied name (EnumProp("Tool")), which by definition cannot be enumerated.

  • Compound, dotted property paths (Tool.Id, Tool.GoToPar.Speed, Part.Temperature, …), since those are compositions built from a parameter-block name and a leaf name, not atomic constants - see pyippdme.simulation.tool and pyippdme.simulation.classes.part_class for that namespace instead.

class pyippdme.protocol.parameters.ParameterName(*values)

Every atomic NamedValue/BasicName identifier a built-in class uses on the wire.

Typed helpers that build the argument tuple for NamedValue-shaped commands.

CommandName and ParameterName remove the risk of mistyping a command or argument name; they don’t remove the remaining risk of getting a command’s argument shape wrong - how many arguments, in what order, wrapped how (a bare NamedValue, a nested one, a fixed-order number list, …). A caller using the low-level IppDmeClient API still has to know all of that by hand, e.g. ScanOnCurve’s three-argument, fixed-Format, flattened- Data shape (see pyippdme.simulation.classes.scanning_class’s module docstring).

Each function here builds exactly the tuple[Argument, ...] its command needs, so it plugs directly into call()/ send() without changing that API at all:

await client.call(CommandName.GO_TO, *go_to(x=10, y=20))

IppDmeMachine (pyippdme.client.model) uses these same functions internally for every command they cover, instead of duplicating the argument-construction logic - so there is exactly one place that knows each command’s wire shape, not two.

These functions only build arguments; they never validate values (e.g. go_to() with every axis None is accepted here and left for the server’s own error response) - matching this project’s existing split between construction and validation (validation happens server-side, see pyippdme.server.classes).

bare_names()/named_numbers() are the generic building blocks the per-command functions below are written in terms of; they are public so a caller building a proprietary/vendor-extension command that isn’t covered by a dedicated function here can still reach for the same recurring shapes (a bare name per argument, a plain named number) instead of constructing NamedValue directly. Mirrors pyippdme.server.builders’s own generic helpers on the response side.

pyippdme.client.builders.bare_names(*names: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build one empty-argument NamedValue per name, e.g. Get(X(), Y()).

pyippdme.client.builders.named_numbers(*named: tuple[str, float | None]) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build one NamedValue(name, (Number,)) per non-None pair, in the order given.

class pyippdme.client.builders.ToolAlignment(primary: tuple[float, float, float], secondary: tuple[float, float, float] | None = None)

A tool orientation: the primary direction and, optionally, the secondary one (6.20).

class pyippdme.client.builders.PartAlignment(part_vector: tuple[float, float, float], machine_vector: tuple[float, float, float], alpha: float, second_part_vector: tuple[float, float, float] | None = None, second_machine_vector: tuple[float, float, float] | None = None, beta: float | None = None)

The rotary-table orientation AlignPart asks for (6.23.1).

second_part_vector, second_machine_vector and beta are for a second rotary table, orthogonal to the first.

pyippdme.client.builders.go_to(x: float | None = None, y: float | None = None, z: float | None = None, *, r: float | None = None, a: float | None = None, b: float | None = None, c: float | None = None, alignment: ToolAlignment | None = None, sync: bool | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build GoTo’s argument list, e.g. go_to(x=10, y=20) -> (X(10), Y(20)).

pyippdme.client.builders.step(x: float | None = None, y: float | None = None, z: float | None = None, *, r: float | None = None, a: float | None = None, b: float | None = None, c: float | None = None, sync: bool | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build Step’s argument list (6.8.1’s relative move).

pyippdme.client.builders.pt_meas(x: float | None = None, y: float | None = None, z: float | None = None, *, ijk: tuple[float, float, float] | None = None, r: float | None = None, a: float | None = None, b: float | None = None, c: float | None = None, alignment: ToolAlignment | None = None, align_part: PartAlignment | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build PtMeas’s argument list.

pyippdme.client.builders.get(*axes: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build Get’s argument list, e.g. get("X", "Y", "R").

pyippdme.client.builders.on_pt_meas_report(*axes: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build OnPtMeasReport’s argument list.

pyippdme.client.builders.get_scale_temperatures(*axes: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build GetScaleTemperatures’ argument list.

pyippdme.client.builders.lock_axis(*axes: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build LockAxis’s argument list.

pyippdme.client.builders.lock_position(*positions: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build LockPosition’s argument list.

pyippdme.client.builders.enum_prop(reference: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build EnumProp’s argument list.

pyippdme.client.builders.enum_all_prop(reference: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build EnumAllProp’s argument list.

pyippdme.client.builders.get_prop(*names: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build GetProp’s argument list, e.g. get_prop("Tool.GoToPar.Speed").

pyippdme.client.builders.set_prop(name: str, value: float | str | Sequence[float]) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build SetProp’s argument for one property: a number, a string or several numbers.

pyippdme.client.builders.set_scale_temperatures(**temperatures: float) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build SetScaleTemperatures’ argument list, e.g. set_scale_temperatures(X=21.0).

pyippdme.client.builders.go_to_on_circle(center: tuple[float, float, float], ijk: tuple[float, float, float], target: tuple[float, float, float]) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build GoToOnCircle’s argument list.

pyippdme.client.builders.go_to_on_spiral(center: tuple[float, float, float], ijk: tuple[float, float, float], target: tuple[float, float, float]) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build GoToOnSpiral’s argument list (the same shape as GoToOnCircle).

pyippdme.client.builders.on_scan_report(*fields: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build OnScanReport’s argument list, e.g. on_scan_report("X", "Y", "Z").

pyippdme.client.builders.set_csy_transformation(transform: CoordinateTransform) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build the X0, Y0, Z0, Theta, Psi, Phi group shared by the csy-transform commands.

This is a fixed-order positional number list, not NamedValue- wrapped (unlike every other builder here) - the standard sends it that way on the request side (only the GetCsyTransformation response wraps the same six values as NamedValue``s). The caller still passes the leading csy name (``BasicName/String) itself, since it isn’t part of this group.

class pyippdme.client.builders.CurvePoint(position: tuple[float, float, float], normal: tuple[float, float, float], tag: int, primary: tuple[float, float, float] | None = None, secondary: tuple[float, float, float] | None = None, rotary: float | None = None)

One nominal point of a ScanOnCurve (Table 85).

tag is +1 (on the part surface) or -1 (no contact expected). primary and secondary are the nominal tool directions at the point (see AlignTool; secondary needs primary) and rotary is the rotary-table angle. Every point of one scan must give the same optional columns.

pyippdme.client.builders.scan_on_curve(points: Sequence[CurvePoint], *, closed: bool = False, rotary_table: bool | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build ScanOnCurve’s argument list from a sequence of nominal points.

pyippdme.client.builders.vector(name: str, value: tuple[float, float, float]) → NamedValue

Build a three-number named argument such as IJK(0,0,1).

pyippdme.client.builders.pt_meas_self_center(x: float | None = None, y: float | None = None, z: float | None = None, ijk: tuple[float, float, float] | None = None, lmn: tuple[float, float, float] | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build PtMeasSelfCenter’s (or, with lmn, PtMeasSelfCenterLocked’s) arguments.

pyippdme.client.builders.on_move_report(time: float, dis: float, axes: Sequence[str]) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build OnMoveReport’s argument list, e.g. Time(0.5), Dis(1), X(), Y().

pyippdme.client.builders.align_tool(primary: tuple[float, float, float], alpha: float, secondary: tuple[float, float, float] | None = None, beta: float | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build AlignTool’s arguments: i1,j1,k1,alpha or all of i1..k2,alpha,beta.

pyippdme.client.builders.alignment_axis(namespace: str, axis: str) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build CalcToolAlignment’s argument, e.g. Tool.A().

pyippdme.client.builders.alignment_vectors(namespace: str, primary: tuple[float, float, float], secondary: tuple[float, float, float] | None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build CalcToolAngles’ argument, e.g. Tool.Alignment(i1,j1,k1[,i2,j2,k2]).

pyippdme.client.builders.raw_data_bin_setup(data_format: str, port: int, live_mode: bool) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build RawDataBinSetup’s arguments.

pyippdme.client.builders.scan_on_circle(center: tuple[float, float, float], start: tuple[float, float, float], normal: tuple[float, float, float], delta: float, surface_angle: float, step_width: float, rotary_table: bool | None = None, *, pitch: float | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build ScanOnCircle’s (or, with pitch, ScanOnHelix’s) positional arguments.

pyippdme.client.builders.density(dis: float | None = None, angle: float | None = None, angle_base_length: float | None = None, at_nominals: bool | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build ScanOnCurveDensity’s/ScanUnknownDensity’s optional named arguments.

pyippdme.client.builders.positional(*parts: float | bool | tuple[float, float, float] | None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build bare positional numbers, flattening vectors, for the fixed-order scan commands.

pyippdme.client.builders.align_part(alignment: PartAlignment) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build AlignPart’s positional arguments.

class pyippdme.client.builders.AcquisitionPoint(position: tuple[float, float, float], primary: tuple[float, float, float], secondary: tuple[float, float, float])

One position of a DataAcquire path (Table 95).

primary is the vector anti-parallel to the tool’s main axis and secondary the one describing the orientation within the working plane (see AlignTool).

pyippdme.client.builders.data_acquire(acq_name: str, acquisition_type: str, settings_name: str, points: Sequence[AcquisitionPoint] = (), *, step_width: float | None = None, rotary_table: bool | None = None) → tuple[Number | String | NamedValue | EventTag | BasicName, ...]

Build DataAcquire’s positional arguments.

Async I++ DME server (section 5).

Execution model (5.4.3 “transactions may overlap”, 5.7 “Prioritized Execution”): a command whose name does not end in E goes onto a single-consumer queue and is executed strictly in the order received - “the standard command queue”. A command whose name does end in E bypasses that queue and starts executing immediately, concurrently with whatever the queue is currently working on - this is the literal rule the standard gives for telling prioritized commands apart (“commands for the prioritized execution end with an upper-case E… to be independent from the transport layer”). AbortE() is additionally handled at the connection level rather than as a registry handler, since aborting requires reaching into this connection’s own queue/task bookkeeping (cancel whatever is currently executing, reject whatever is still queued) - not something a generic per-command handler can do.

A command’s CommandContext carries a per-transaction CancellationToken that AbortE() sets before cancelling its task, so a streaming handler (see ScanOnLine/ScanOnCircle in pyippdme.simulation.classes.scanning_class) gets both signals: the token, for cooperative/explicit checks, and asyncio.CancelledError at its next await point.

A bare IppDmeServer registers no commands (command_classes defaults to ()) and builds a plain MachineState per connection. See VirtualCMM for a server with simulated command classes.

class pyippdme.server.IppDmeServer(*, backend: ~pyippdme.server.backend.MachineBackend | None = None, csy_store: ~pyippdme.types.csy.CsyStore | None = None, machine_class: str | ~collections.abc.Sequence[str] = 'CartCMM_TouchTrigger_Fixed_None_None_None_None', command_classes: ~collections.abc.Sequence[~collections.abc.Callable[[~pyippdme.server.registry.CommandRegistry], None]] = (), state_factory: ~collections.abc.Callable[[], ~pyippdme.server.registry.StateT] = <class 'pyippdme.server.registry.MachineState'>, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, sample_surface: ~pyippdme.server.surface.SampleSurface | None = None, raw_sensor: ~pyippdme.server.surface.RawSensor | None = None, motion: ~pyippdme.server.motion.MotionModel | None = None, tool_handler: ~pyippdme.server.motion.ToolHandler | None = None, on_line_received: ~collections.abc.Callable[[str], None] | None = None, on_line_sent: ~collections.abc.Callable[[str], None] | None = None, on_connect: ~collections.abc.Callable[[str], None] | None = None, on_disconnect: ~collections.abc.Callable[[str], None] | None = None, max_pending: int | None = None)

An I++ DME server that registers no command classes by default.

IppDmeServer() alone registers nothing - not even Server/DME - and needs no per-connection state beyond the bare MachineState. Pass command_classes to register any mix of pyippdme.server.classes (the two mandatory ones), pyippdme.simulation.classes (this library’s own bundled reference simulation - see VirtualCMM for a server pre-loaded with all of them), or your own - each element is a register(registry) function applied in order:

from pyippdme.server.classes import register_dme_class, register_server_class

server = IppDmeServer(command_classes=[register_server_class, register_dme_class])

@server.registry.command_proprietary("XX", "MyCommand")
async def _my_command(ctx, args):
    ...

Section 6.1 requires a two-character company namespace for any command not defined by the standard, so prefer command_proprietary() over command() for your own. The standard mandates Server and DME for a conformant implementation; this is not enforced here, so intentionally-partial or test servers remain possible.

To keep only some commands from a class you otherwise want (e.g. a Scanning backend that only ever does ScanOnLine, not ScanOnCircle/ScanOnHelix), use register_subset() instead of hand-writing a matching unregister() call per command you don’t want - commands_of() answers “what would this class register” if you need that list for anything else:

server = IppDmeServer(command_classes=[register_server_class, register_dme_class])
register_subset(server.registry, register_scanning_class, keep={CommandName.SCAN_ON_LINE})

For a new command class (built-in or your own) where you want a method’s own parameters typed instead of a raw argument tuple, and its registered commands always kept truthfully in sync with what GetSupportedCommands() reports without a separate call, write it as a plain object with @command/@command_proprietary-decorated methods and pass it to register_object() instead; see pyippdme.server.dispatch.

Pass backend for the Scanning class’s real hardware control (see pyippdme.server.backend) - None (the default) is only a problem if a registered handler actually needs one and none was given. Pass csy_store to persist named coordinate systems across restarts, e.g. FileCsyStore(); see pyippdme.types.csy (the in-memory default does not). Pass machine_class to override the string every connection’s GetMachineClass() reports (6.4.1). Pass sample_surface to give PtMeas (6.12.1) a real synthetic part to measure against instead of always reporting exactly the commanded position; see pyippdme.server.surface. Pass state_factory if any registered command class needs more per-connection state than MachineState itself provides (see SimulationState for this library’s own bundled simulation’s extension) - it must build the same concrete type StateT this server is parameterized over. Pass network to listen somewhere other than TCP, e.g. a MemoryNetwork for connections that stay inside the process. Pass on_line_received/on_line_sent/on_connect/on_disconnect for observe-only wire-level visibility (e.g. ippdme serve --session-log); see pyippdme.protocol.hooks.

max_pending

How many acknowledged commands may wait for the one that runs; a further command is acknowledged only when there is room (5.4.3). None acknowledges at once.

network

Where this server’s listener (and anything a handler has to open) comes from.

sample_surface

The synthetic part PtMeas measures against, if any; see pyippdme.server.surface. None (the default) keeps PtMeas reporting the commanded position exactly.

raw_sensor

The simulated optical sensor behind DataAcquire; see RawSensor.

motion

What carries out a move; see MotionModel.

tool_handler

Tool change and qualification; see ToolHandler.

on_line_received

Observe-only wire-line hooks (see pyippdme.protocol.hooks), named from this server’s own point of view: on_line_received fires for a line a client sent it (a command), on_line_sent for a line it sent back (a response) - the mirror image of IppDmeClient’s hooks of the same name. Per 5.8, only one client is ever connected at a time, so unlike Spy’s hooks these carry no connection identifier to disambiguate.

on_connect

Called with the peer’s address (host:port) on each new connection/disconnection.

async start(host: str = '127.0.0.1', port: int = 0) → int

Bind and start accepting connections without blocking; return the bound port.

Unlike serve_forever() (which blocks the caller until cancelled), this returns as soon as the listening socket is up - for embedding the server in-process alongside other work in the same event loop (a REPL/TUI driving it directly, a test fixture, …) rather than running it as a standalone process. port=0 (the default) lets the network pick a free port, returned here so the caller can connect to it. Call close() when done.

property port: int | None

The port currently bound by start()/serve_forever(), or None.

property active_state: StateT | None

The state of the connected client, or None; only one is connected at a time (5.8).

async send_event(payload: NumericData | PropertyData | Items | StringValue | NameValue | Xml) → bool

Send an unsolicited event (tag E0000, 5.5.1) to the connected client.

Returns whether a client was connected. See pyippdme.server.builders for the pre-defined events of 5.5.3.

This library’s own bundled reference simulation, built on the core pyippdme.server.

A bare IppDmeServer registers nothing and knows nothing about simulated machine behavior (see its own docstring); this package is where that behavior actually lives - fake position tracking, a fake tool catalog, fake scan geometry, and the rest of what VirtualCMM bundles together so a client implementer has something to develop and test against without real hardware. pyippdme.simulation.state’s SimulationState extends the core’s minimal MachineState with exactly that fake state, and pyippdme.simulation.classes is where the command handlers that own it live.

pyippdme.simulation.DEFAULT_COMMAND_CLASSES: Sequence[Callable[[CommandRegistry], None]] = (<function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>)

Every command class this library’s own simulation bundles, in registration order - what VirtualCMM registers by default, and the reference set pyippdme.server.dispatch reads a standard command’s argument schema from.

A ready-to-run, fully simulated CMM for client development (no hardware required).

Real dimensional-metrology hardware is expensive, so a client implementer needs something to develop and test against. VirtualCMM is exactly IppDmeServer with every built-in command class enabled and sensible defaults for standalone use:

  • machine_class reports the _VirtualCMM suffix 6.4.1 reserves for exactly this case (“specifies whether the server provides a virtual CMM and not a real one”), and - unlike IppDmeServer’s fixed default - is derived from command_classes (see default_machine_class()), since a simulated machine’s configuration is fully known from what was actually registered, unlike a real backend’s.

  • csy_store defaults to FileCsyStore, so named coordinate systems saved during one run are still there the next time - matching 6.5.2’s “must be stored persistently” requirement, unlike IppDmeServer’s own in-memory default (chosen there so a plain IppDmeServer() never touches disk unasked).

Everything else is inherited unchanged; pass backend= for custom scanning geometry, or command_classes= to still trim which classes are active, exactly as on IppDmeServer.

pyippdme.simulation.virtual_cmm.default_machine_class(command_classes: Sequence[Callable[[CommandRegistry], None]]) → str

Derive a 6.4.1 machine-class string from which command_classes are registered.

Server becomes “CartCMM” if cartcmm is present, else “None”. Tool becomes “Scanning” if scanning is present (4.2: a strictly more specific claim than plain single-point measurement), else “TouchTrigger” if tool is present, else “None” - note this can only report one of the two even when a machine implements both; 6.4.1’s own answer for that (“if a server implements more than one machine class, multiple strings are sent”) would need GetMachineClass() itself to return more than one value, which it doesn’t here. Alignment stays fixed at “Fixed”. Each of Mover/ToolChanger/Part/RotaryTable becomes its class name if present, else “None” (6.4.1), followed by the VirtualCMM suffix. Passing the full DEFAULT_COMMAND_CLASSES reproduces the same string VirtualCMM has always defaulted to.

pyippdme.simulation.virtual_cmm.VIRTUAL_CMM_MACHINE_CLASS = 'CartCMM_Scanning_Fixed_Cartesian_ToolChanger_Part_RotaryTable_VirtualCMM'

default_machine_class() for the full DEFAULT_COMMAND_CLASSES set - VirtualCMM’s machine_class when every built-in class is active.

class pyippdme.simulation.virtual_cmm.VirtualCMM(*, backend: ~pyippdme.server.backend.MachineBackend | None = None, csy_store: ~pyippdme.types.csy.CsyStore | None = None, machine_class: str | None = None, command_classes: ~collections.abc.Sequence[~collections.abc.Callable[[~pyippdme.server.registry.CommandRegistry], None]] = (<function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>, <function register>), network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, sample_surface: ~pyippdme.server.surface.SampleSurface | None = None, raw_sensor: ~pyippdme.server.surface.RawSensor | None = None, motion: ~pyippdme.server.motion.MotionModel | None = None, tool_handler: ~pyippdme.server.motion.ToolHandler | None = None, on_line_received: ~collections.abc.Callable[[str], None] | None = None, on_line_sent: ~collections.abc.Callable[[str], None] | None = None, on_connect: ~collections.abc.Callable[[str], None] | None = None, on_disconnect: ~collections.abc.Callable[[str], None] | None = None, max_pending: int | None = None)

A fully simulated CMM, ready to serve_forever() with no further setup.

import asyncio
from pyippdme.simulation.virtual_cmm import VirtualCMM

asyncio.run(VirtualCMM().serve_forever(host="127.0.0.1"))
async key_press(key: str) → bool

Press a key on the virtual jog box; the client gets KeyPress(key).

The event is sent only while the user is enabled (5.5.3); returns whether it was sent.

async clearance_point(x: float, y: float, z: float) → bool

Set a clearance point by hand: the machine moves there; the client gets GoTo(...).

async manual_point(x: float, y: float, z: float, ijk: tuple[float, float, float] = (0.0, 0.0, 0.0)) → bool

Pick a point by hand: the client gets PtMeas(...) with the report fields.

async change_tool(tool_name: str) → bool

Change the tool at the machine: the client gets ChangeTool(ToolName) (5.5.3).

async data_acquire(acq_name: str, acquisition_type: str, settings_name: str, points: Sequence[tuple[tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]]] = ()) → bool

Take a measurement at the machine: the client gets DataAcquire(...) (6.15).

Like the other unsolicited events it is sent only while the user is enabled.

async open_tool_collection(path: str) → bool

Open a tool collection at the machine: the client gets OpenToolCollection(path).

async set_property(name: str, *values: float | str) → bool

Change a property at the machine: the client gets SetProp(name(values)) (5.5.3).

Server-side command dispatch: registry, per-connection state, and handler contract.

A CommandHandler receives the parsed argument tuple of the incoming method call and a CommandContext, and returns the data to send back (5.4.2/5.4.3): nothing (just Ack+Done), a single payload, a sequence of payloads each sent as its own # data response line before the final % (e.g. EnumNameSpaces() sending “each namespace in a separate message”), or an async iterator of payloads sent as they are produced rather than materialized up front (used by streaming commands like ScanOnLine/ScanOnCircle, so a client-issued AbortE() can interrupt delivery mid-stream; see pyippdme.server.backend).

MachineState is deliberately minimal: only the session/error/ machine-identity bookkeeping the mandatory Server/DME classes (pyippdme.server.classes) need. A command class that owns further per-connection state (a simulated position, a fake tool catalog, …) extends it by subclassing, not by MachineState itself growing a field per class that might not even be registered - see SimulationState for this library’s own bundled simulation’s extension, and IppDmeServer’s state_factory for how a server is told to build one. CommandContext is generic over the concrete state type for exactly this reason: a handler written against a specific state subclass (ctx: CommandContext[SimulationState]) gets full static type-checking on ctx.state’s extra fields, while the registry itself stores every handler erased to CommandContext[Any] - it never needs to know or care which concrete state type a given server was built with.

pyippdme.server.registry.PropertySetHandler

One command class’s attempt to handle a single SetProp(<name>(<value>)) argument. Returns True if it recognized arg.name and handled it (including by raising a ServerError); False lets the next resolver, or finally the generic per-connection property store, try instead. See CommandRegistry.register_property_resolver().

alias of Callable[[CommandContext[Any], NamedValue], bool]

pyippdme.server.registry.PropertyGetHandler

returns the resolved NamedValue if this resolver recognized arg.name, or None to let the next resolver (or the generic store) try.

Type:

The GetProp counterpart of PropertySetHandler

alias of Callable[[CommandContext[Any], NamedValue], NamedValue | None]

pyippdme.server.registry.PropertyChildrenHandler

One command class’s attempt to list the direct children of a property reference (EnumProp/EnumAllProp, 6.3.1.1). Returns each child as (name, type) where type is one of Table 20’s own vocabulary - "Number", "String", or "Property" (the last meaning the child itself has further children an EnumAllProp should recurse into) - or None if this class doesn’t recognize reference at all, letting the next resolver try. See CommandRegistry.register_property_children().

alias of Callable[[CommandContext[Any], str], tuple[tuple[str, str], …] | None]

pyippdme.server.registry.DaemonStopHandler

One command class’s attempt to stop a StopDaemon/StopAllDaemons (6.3.1) target: given the event tag StopDaemon named (None for StopAllDaemons, “every daemon”), stop and forget whatever daemon(s) it owns that match, returning True if it recognized/handled at least one. See CommandRegistry.register_daemon_stopper().

alias of Callable[[CommandContext[Any], EventTag | None], bool]

pyippdme.server.registry.SessionLifecycleHandler

One command class’s reaction to a session-lifecycle event (StartSession/EndSession/ClearAllErrors, 6.3) - e.g. resetting a modal flag that the standard says one of these resets, or releasing resources a session held. See CommandRegistry.register_session_start_hook()/ register_session_end_hook()/ register_clear_errors_hook().

alias of Callable[[CommandContext[Any]], None]

class pyippdme.server.registry.PropertyKind(*values)

Table 20’s EnumProp/EnumAllProp child-type vocabulary.

pyippdme.server.registry.DEFAULT_MACHINE_CLASS = 'CartCMM_TouchTrigger_Fixed_None_None_None_None'

The default GetMachineClass() string (6.4.1’s naming scheme), also used as IppDmeServer’s default; see pyippdme.simulation.virtual_cmm for the _VirtualCMM-suffixed variant.

class pyippdme.server.registry.MachineState(session_active: bool = False, active_error: ServerError | None = None, homed: bool = False, home_position: tuple[float, float, float] | None=None, machine_class: str | tuple[str, ...]='CartCMM_TouchTrigger_Fixed_None_None_None_None', dme_version: str = '2.5', properties: dict[str, tuple[~pyippdme.protocol.ast.Number | ~pyippdme.protocol.ast.String | ~pyippdme.protocol.ast.NamedValue | ~pyippdme.protocol.ast.EventTag | ~pyippdme.protocol.ast.BasicName, ...]]=<factory>)

Per-connection state used by the mandatory Server/DME classes (6.3/6.4).

Deliberately minimal - just session lifecycle, error handling, machine identity, and the generic SetProp/GetProp fallback property store, since those are the only things pyippdme.server.classes (the two classes every conformant server needs, real or simulated) ever touch. A command class that needs more per-connection state than this - which is every other built-in class, all of them simulated - extends it by subclassing, e.g. SimulationState; IppDmeServer’s state_factory constructor argument is how a server is told to build that subclass instead of a plain MachineState. This keeps MachineState itself from growing a field per command class regardless of whether that class is even registered on a given server.

home_position: tuple[float, float, float] | None

Where Home() left the machine in the coordinates a client sees; None if the machine’s own home position applies (set by a motion model, see MotionModel.home).

properties: dict[str, tuple[Number | String | NamedValue | EventTag | BasicName, ...]]

Generic fallback store for SetProp/GetProp on properties not modeled individually by a built-in class, keyed by dotted property name.

carry_over_from(previous: MachineState) → None

Take over what the server keeps between clients (6.3.1: EndSession/StartSession).

The machine keeps being homed. A subclass adds the state of the command classes it owns: the active tool, the active coordinate system and the part.

class pyippdme.server.registry.CommandContext(tag: ~pyippdme.protocol.ast.Tag | ~pyippdme.protocol.ast.EventTag, state: ~pyippdme.server.registry.StateT, registry: ~pyippdme.server.registry.CommandRegistry, backend: ~pyippdme.server.backend.MachineBackend | None, csy_store: ~pyippdme.types.csy.CsyStore, cancel: ~asyncio.locks.Event, sample_surface: ~pyippdme.server.surface.SampleSurface | None = None, raw_sensor: ~pyippdme.server.surface.RawSensor | None = None, motion: ~pyippdme.server.motion.MotionModel | None = None, tool_handler: ~pyippdme.server.motion.ToolHandler | None = None, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, emit_event: ~collections.abc.Callable[[~pyippdme.protocol.ast.Tag | ~pyippdme.protocol.ast.EventTag, ~pyippdme.protocol.ast.NumericData | ~pyippdme.protocol.ast.PropertyData | ~pyippdme.protocol.ast.Items | ~pyippdme.protocol.ast.StringValue | ~pyippdme.protocol.ast.NameValue | ~pyippdme.protocol.ast.Xml], ~collections.abc.Awaitable[None]] | None = None)

Everything a command handler needs, besides the raw argument tuple.

backend: MachineBackend | None

The Scanning class’s real-hardware seam (see pyippdme.server.backend); None if the server wasn’t given one - only a problem for a handler that actually needs it (a Scanning-class one), which should check and raise a clear error rather than let it surface as an AttributeError.

csy_store: CsyStore

Persistence for named coordinate systems (6.5.2); see pyippdme.types.csy.

cancel: Event

Set when this specific transaction must stop as soon as possible (e.g. the client sent AbortE()); see pyippdme.server.backend.

sample_surface: SampleSurface | None

The synthetic part PtMeas measures against, if any - see pyippdme.server.surface. None (the default) keeps PtMeas reporting the commanded position exactly, as if nothing were ever really touched.

raw_sensor: RawSensor | None

The simulated optical sensor DataAcquire uses, if any; see RawSensor.

motion: MotionModel | None

What carries out a move (time, limits, collisions); see MotionModel. None: moves are instant.

tool_handler: ToolHandler | None

Tool change and qualification; see ToolHandler.

network: Network

Where a handler that has to open its own connection or listener (the raw-data binary socket, 6.17.2.1) gets it from; the server’s own Network.

emit_event: Callable[[Tag | EventTag, NumericData | PropertyData | Items | StringValue | NameValue | Xml], Awaitable[None]] | None

Sends one extra data message tagged with something other than this transaction’s own tag - the seam a handler uses to push an OnMoveReport/OnMoveReportE daemon’s report (see pyippdme.simulation.classes.mover_class) alongside its own normal response, without that daemon’s EventTag being confused for this command’s completion. None in a context built outside a real connection (e.g. a unit test), where there is nowhere for it to go.

class pyippdme.server.registry.CommandRegistry

Maps method names to CommandHandler callables.

Populated by default with nothing - IppDmeServer registers whatever command_classes it was given, typically starting with the mandatory Server/DME classes from pyippdme.server.classes (see pyippdme.simulation for this library’s own bundled simulated classes, none of which are registered unless asked for). Additional command classes can be registered the same way, either by calling register() directly or via the command() decorator. VDMA 8722 6.1 requires any command not defined by the standard to be prefixed with a two-character company namespace; register_proprietary()/ command_proprietary() build and validate that for you (see pyippdme.protocol.namespace) instead of registering a bare name that might collide with a future standard command.

arguments is optional, spec-derived metadata (see pyippdme.protocol.signature) used only to answer GetSupportedArguments(CommandName) (6.4.1); a command registered without it still works normally, GetSupportedArguments just cannot describe it (0506 “Argument not supported”). Pass arguments=() (rather than omitting the keyword) for a command that is fully described and genuinely takes no arguments at all (Home(), StartSession(), …) - arguments() distinguishes “no schema on record” (None) from “on record, and it is empty” (()), so GetSupportedArguments can report the latter as a real, supported, zero-argument command instead of “not supported”.

register_proprietary(namespace: str, name: str, handler: Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]], *, arguments: tuple[Parameter, ...] | None = None) → None

Register a command under a two-letter company namespace (6.1).

unregister(name: str) → None

Remove a command, e.g. to drop one a chosen built-in class doesn’t need.

A no-op if name isn’t registered.

command(name: str, *, arguments: tuple[Parameter, ...] | None = None) → Callable[[Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]

Register as a decorator; arguments means the same thing as in register().

command_proprietary(namespace: str, name: str, *, arguments: tuple[Parameter, ...] | None = None) → Callable[[Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]], Callable[[CommandContext[Any], tuple[Number | String | NamedValue | EventTag | BasicName, ...]], Awaitable[NumericData | PropertyData | Items | StringValue | NameValue | Xml | Sequence[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml] | None]]]

Register as a decorator; arguments is as in register_proprietary().

register_property_resolver(*, setter: Callable[[CommandContext[Any], NamedValue], bool] | None = None, getter: Callable[[CommandContext[Any], NamedValue], NamedValue | None] | None = None) → None

Let a command class handle a subset of SetProp/GetProp properties.

SetProp(Tool.PtMeasPar.Retract.Act(5)) and SetProp(Part.Temperature(21)) both dispatch through the single Server class SetProp/GetProp handlers (pyippdme.server.classes.server_class), which is the only place the wire format actually names - the standard does not prefix commands by class. Rather than every property-owning class (pyippdme.simulation.classes.tool_class, pyippdme.simulation.classes.part_class, …) overriding those two handlers wholesale, which would make each newly-registered class silently clobber the previous one’s property handling, each contributes a resolver here instead; the Server handlers try them in registration order and fall back to the plain per-connection property store (generic_set_prop()/ generic_get_prop()) if none matches.

register_property_children(handler: Callable[[CommandContext[Any], str], tuple[tuple[str, str], ...] | None]) → None

Let a command class answer EnumProp/EnumAllProp for a subset of references.

Mirrors register_property_resolver(): EnumProp/EnumAllProp dispatch through the single Server class handlers (6.3.1.1), and each property-owning class contributes what it knows about its own references here instead of those handlers hard-coding every class’s object tree.

register_daemon_stopper(handler: Callable[[CommandContext[Any], EventTag | None], bool]) → None

Let a command class handle StopDaemon/StopAllDaemons (6.3.1) for its own daemons.

Mirrors register_property_resolver(): StopDaemon/ StopAllDaemons dispatch through the single Server class handlers (pyippdme.server.classes.server_class), which have no daemon of their own to stop - only a class that actually starts one (e.g. pyippdme.simulation.classes.mover_class’s OnMoveReport/OnMoveReportE) does, so Server dispatches to whichever registered stopper(s) recognize the target instead of hard-coding a specific daemon-owning class by name.

register_session_start_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to StartSession() (6.3), e.g. resetting a modal flag.

StartSession itself (pyippdme.server.classes.server_class) knows nothing about any specific class’s state - a class whose commands establish a documented “reset to this on StartSession” default (e.g. Alignable_AB’s UseSmallestAngletoAlignTool) registers a hook here instead of server_class reaching into it directly.

register_session_end_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to EndSession() (6.3), e.g. releasing held resources.

Mirrors register_session_start_hook(); see e.g. pyippdme.simulation.classes.rawdata_class’s buffered acquisitions, which EndSession() “implicitly deletes” (6.15.1).

register_clear_errors_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to ClearAllErrors() (6.3), e.g. resetting a modal flag.

Mirrors register_session_start_hook().

register_home_hook(handler: Callable[[CommandContext[Any]], None]) → None

Let a command class react to Home() (6.4), e.g. Mover’s implicit DisableUser.

Mirrors register_session_start_hook(): Home() (pyippdme.server.classes.dme_class) is mandatory and knows nothing about any specific class’s state, but the standard says it triggers side effects on other classes anyway (6.7.1’s “Server Remarks” under DisableUser(): implicitly called by any command that physically moves the machine, Home() included).

arguments(name: str) → tuple[Parameter, ...] | None

Return name’s declared Parameter tuple.

None means no schema is on record at all; () means one is, and it says name takes no arguments - see register().

pyippdme.server.registry.commands_of(register_fn: Callable[[CommandRegistry], None]) → tuple[str, ...]

Return the command names register_fn would register, without a real registry.

There is no separate, hand-maintained list of “Scanning’s commands” (or any other class’s) anywhere - a register_*_class function’s own body is that list, so this reads it from the one place it can’t drift out of sync: by actually calling it against a scratch registry.

pyippdme.server.registry.component_name(register_fn: Callable[[CommandRegistry], None]) → str

Return the short name a register_*_class function stands for, e.g. "cartcmm".

Read from the module register_fn is defined in (pyippdme.simulation.classes.cartcmm_class -> "cartcmm"), not its __name__ - every one of these functions is named plainly register in its own module and only gets an alias like register_cartcmm_class when re-exported from pyippdme.server.classes/pyippdme.simulation.classes, and __name__ doesn’t follow that alias. Used wherever a caller needs to refer to “which command classes” by name (CLI flags, a machine-class string derived from them) without a second, hand-maintained name-to-function table that could drift from what it actually names.

pyippdme.server.registry.register_subset(registry: CommandRegistry, register_fn: Callable[[CommandRegistry], None], keep: Iterable[str]) → None

Register everything register_fn defines, then drop whatever isn’t in keep.

For picking which commands within one command class a particular server instance actually supports (e.g. a vision-only Scanning backend that does ScanOnLine but not ScanOnCircle/ScanOnHelix) - IppDmeServer’s own command_classes parameter already covers picking whole classes; this is the same idea one level finer, without hand-writing a matching CommandRegistry.unregister() call per command you don’t want. GetSupportedCommands()/ GetSupportedArguments() (6.4.1) reflect the result correctly, since they read the registry directly - nothing dropped here is ever registered in the first place from a caller’s perspective.

Commands register_fn would have registered anyway (because keep included them, or because they were already present before this call) are left untouched either way.

Per-connection state for this library’s bundled simulated command classes.

Each nested dataclass here is owned by exactly one pyippdme.simulation.classes module; SimulationState bundles them all as an extension of the core MachineState (session/error/identity only), which is all pyippdme.server.classes’ mandatory Server/ DME classes need. A real integrator with their own command classes would define their own such extension the same way, rather than reusing this one - see IppDmeServer’s state_factory.

class pyippdme.simulation.state.CartCmmState(active_csy: str = 'MachineCsy', position: tuple[float, float, float]=(0.0, 0.0, 0.0), pt_meas_report: tuple[str, ...]=(), csy_transformations: dict[str, ~pyippdme.types.csy.CoordinateTransform]=<factory>)

State owned by pyippdme.simulation.classes.cartcmm_class (6.5, 6.8, 6.12).

pt_meas_report: tuple[str, ...]

Axis names requested by the last OnPtMeasReport(...); empty until set.

csy_transformations: dict[str, CoordinateTransform]

Live (this-connection-only) transforms set by SetCsyTransformation (6.5.2), keyed by one of LIVE_TRANSFORM_NAMES. Unlike named/saved transforms (see CsyStore), these are never persisted.

class pyippdme.simulation.state.ToolState(parameters: ~pyippdme.server.tool.ToolParameters = <factory>, active_name: str = 'RefTool', found_name: str | None = None, last_qualified: dict[str, str] = <factory>, alignment: dict[str, tuple[tuple[float, float, float], tuple[float, float, float] | None]] = <factory>, open_collection: str | None = None, use_smallest_angle: bool = False, optimize_enabled: bool = False)

State owned by tool_class/toolchanger_class (6.10/6.22).

See pyippdme.simulation.classes.

parameters: ToolParameters

GoToPar/PtMeasPar/ScanPar parameter blocks of the active tool (6.10.4); see pyippdme.simulation.tool.

active_name: str

Name of the currently active tool, changed by ChangeTool/SetTool (6.22.1); a key into pyippdme.simulation.classes.tool_class.TOOL_CATALOG.

found_name: str | None

Name of the tool last resolved by FindTool(...), or None if FindTool was never called this session (“otherwise it is UnDefTool”, 6.22.1’s FoundTool()).

last_qualified: dict[str, str]

ISO-8601 UTC timestamp of each tool’s last ReQualify() (6.10.2), keyed by tool name; unset reads as "00000000T000000Z" (“never qualified”, Tool.LastQualified()’s own example format, 6.10.3).

alignment: dict[str, tuple[tuple[float, float, float], tuple[float, float, float] | None]]

the primary vector, and the secondary vector if given. A tool never aligned this session is absent - see tool_alignment() for the default this falls back to.

Type:

Alignment set by AlignTool() (6.20.1), keyed by tool name

open_collection: str | None

Path of the tool collection opened by OpenToolCollection (6.22, Figure 56); tools are then named by the entries of that collection. None: tool names are used as they are.

use_smallest_angle: bool

UseSmallestAngletoAlignTool()’s modal flag (6.20.1) - reset to False by StartSession().

optimize_enabled: bool

Enable/DisableOptimize()’s modal flag (6.20.1) - reset to False by StartSession() and ClearAllErrors().

class pyippdme.simulation.state.ScanningState(report: tuple[str, ...] = ())

State owned by pyippdme.simulation.classes.scanning_class (6.13.2).

report: tuple[str, ...]

Report field names requested by the last OnScanReport(...); empty until set.

class pyippdme.simulation.state.FormTesterState(locked_axes: frozenset[str] = frozenset({}), locked_positions: frozenset[str] = frozenset({}))

State owned by pyippdme.simulation.classes.formtester_class (6.6.1).

locked_axes: frozenset[str]

Axes currently locked by LockAxis(...); read by GoTo/PtMeas to silently ignore motion on these axes.

locked_positions: frozenset[str]

Positions currently locked by LockPosition(...); stored and validated, but not enforced (see pyippdme.simulation.classes.formtester_class).

class pyippdme.simulation.state.MoveReportDaemon(tag: EventTag, axes: tuple[str, ...])

An active OnMoveReport/OnMoveReportE daemon (6.10.2’s Table 68).

axes: tuple[str, ...]

Which X/Y/Z/R/Tool.A/Tool.B/Tool.C fields to report.

class pyippdme.simulation.state.MoverState(user_enabled: bool = True, scale_temperatures: dict[str, float]=<factory>, temperature_compensation_origin: dict[str, float]=<factory>, report_daemon: MoveReportDaemon | None = None)

State owned by pyippdme.simulation.classes.mover_class (6.7.1).

user_enabled: bool

Manual jog box enable state (EnableUser/DisableUser).

scale_temperatures: dict[str, float]

Per-axis scale temperature (Set/GetScaleTemperatures), keyed by axis name; an axis reads as 20.0 until explicitly set.

temperature_compensation_origin: dict[str, float]

Per-axis temperature compensation origin offset (SetTemperatureCompensationOrigin), keyed by X/Y/Z; unset reads as 0.0 (“the zero point of the active coordinate system will be used”).

report_daemon: MoveReportDaemon | None

The active OnMoveReport/OnMoveReportE daemon, if any; see MoveReportDaemon and pyippdme.simulation.classes.mover_class.

class pyippdme.simulation.state.RotaryTableState(position: float = 0.0, second_position: float = 0.0, var_csy_enabled: bool = False)

State owned by pyippdme.simulation.classes.rotarytable_class (6.23).

position: float

Position of the rotary table in degrees (R()/R(r)), read/written as a fourth axis by Get/GoTo/PtMeas.

second_position: float

Position of the second, orthogonal rotary table, set by AlignPart (6.23.1).

var_csy_enabled: bool

Whether rotary-table-CSY calculation is enabled (EnableRotaryTableVarCsy).

class pyippdme.simulation.state.RawDataState(acquisitions: dict[str, ~pyippdme.types.pointcloud.PointCloudSet]=<factory>, bin_format: str | None = None, bin_port: int | None = None, bin_live: bool = False, shared_memory_segments: dict[str, ~multiprocessing.shared_memory.SharedMemory]=<factory>, files: dict[str, ~pathlib.Path]=<factory>)

State owned by pyippdme.simulation.classes.rawdata_class (6.15, 6.17).

acquisitions: dict[str, PointCloudSet]

Raw-data acquisitions buffered by DataAcquire (6.15.1), keyed by AcqName, retrieved via one of GetRawDataBin/GetRawDataShaMem/ GetRawDataFile (6.17.2). “EndSession() implicitly deletes all buffered acquisitions” (6.15.1).

bin_format: str | None

RawDataFormat/Port remembered from the last RawDataBinSetup (6.17.2.1).

bin_live: bool

points are sent while they are acquired.

Type:

LiveMode of the last RawDataBinSetup

shared_memory_segments: dict[str, SharedMemory]

Shared-memory segments opened by GetRawDataShaMem, keyed by AcqName, released by ReleaseShaMem (6.17.2.2).

files: dict[str, Path]

Files written by GetRawDataFile, keyed by AcqName, deleted by DelRawDataFile (6.17.2.3).

class pyippdme.simulation.state.PartState(properties: dict[str, float]=<factory>)

State owned by pyippdme.simulation.classes.part_class (6.24.2).

Keyed by dotted property name (Part.Temperature, …); unset reads as that property’s StartSession() default - see pyippdme.simulation.classes.part_class.

class pyippdme.simulation.state.FeatureState(rois: dict[str, ~typing.Any]=<factory>)

State of the deprecated FeatureExtraction class: the regions of interest by name.

class pyippdme.simulation.state.SimulationState(session_active: bool = False, active_error: ServerError | None = None, homed: bool = False, home_position: tuple[float, float, float] | None=None, machine_class: str | tuple[str, ...]='CartCMM_TouchTrigger_Fixed_None_None_None_None', dme_version: str = '2.5', properties: dict[str, tuple[Argument, ...]]=<factory>, cart_cmm: CartCmmState = <factory>, tool: ToolState = <factory>, scanning: ScanningState = <factory>, form_tester: FormTesterState = <factory>, mover: MoverState = <factory>, rotary_table: RotaryTableState = <factory>, raw_data: RawDataState = <factory>, part: PartState = <factory>, features: FeatureState = <factory>)

Per-connection state for every bundled simulated command class.

State that belongs to exactly one command class is grouped into its own nested dataclass (state.tool.active_name rather than a same-level field), so each class’s state stays discoverable without this class growing without bound as more simulated classes are added. See MachineState for the core fields this extends.

carry_over_from(previous: MachineState) → None

Keep what the machine keeps between clients (6.3.1).

That is the active tool and its properties, the active coordinate system with its transformations, and where the machine stands.

The command catalog of this library’s own bundled simulated classes.

See pyippdme.server.catalog for the generic catalog-building function this is built from - call it yourself for any other command_classes selection; this module just applies it once, to DEFAULT_COMMAND_CLASSES, and freezes the result.

pyippdme.simulation.catalog.BUILTIN_COMMANDS: Mapping[str, CommandInfo] = mappingproxy({<CommandName.ABORT_E: 'AbortE'>: CommandInfo(name=<CommandName.ABORT_E: 'AbortE'>, arguments=()), <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>: CommandInfo(name=<CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>, arguments=()), <CommandName.ALIGN_PART: 'AlignPart'>: CommandInfo(name=<CommandName.ALIGN_PART: 'AlignPart'>, arguments=(Parameter(name='px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mx1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='my1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='px2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='py2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mx2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='my2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.ALIGN_TOOL: 'AlignTool'>: CommandInfo(name=<CommandName.ALIGN_TOOL: 'AlignTool'>, arguments=(Parameter(name='i1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='j2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='k2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.AVR_RADIUS: 'AvrRadius'>: CommandInfo(name=<CommandName.AVR_RADIUS: 'AvrRadius'>, arguments=()), <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>: CommandInfo(name=<CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>: CommandInfo(name=<CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>, arguments=(Parameter(name='Alignment', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.CENTER_PART: 'CenterPart'>: CommandInfo(name=<CommandName.CENTER_PART: 'CenterPart'>, arguments=(Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.CHANGE_TOOL: 'ChangeTool'>: CommandInfo(name=<CommandName.CHANGE_TOOL: 'ChangeTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>: CommandInfo(name=<CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>, arguments=()), <CommandName.DATA_ACQUIRE: 'DataAcquire'>: CommandInfo(name=<CommandName.DATA_ACQUIRE: 'DataAcquire'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='Type', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='AcquiseSettingsName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True))), <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>: CommandInfo(name=<CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), 'DeleteAcquisition': CommandInfo(name='DeleteAcquisition', arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>: CommandInfo(name=<CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>: CommandInfo(name=<CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>, arguments=()), <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>: CommandInfo(name=<CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>: CommandInfo(name=<CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>, arguments=()), <CommandName.DISABLE_USER: 'DisableUser'>: CommandInfo(name=<CommandName.DISABLE_USER: 'DisableUser'>, arguments=()), <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>: CommandInfo(name=<CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>, arguments=()), <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>: CommandInfo(name=<CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>, arguments=(Parameter(name='Bool', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True),)), <CommandName.ENABLE_USER: 'EnableUser'>: CommandInfo(name=<CommandName.ENABLE_USER: 'EnableUser'>, arguments=()), <CommandName.END_SESSION: 'EndSession'>: CommandInfo(name=<CommandName.END_SESSION: 'EndSession'>, arguments=()), <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>: CommandInfo(name=<CommandName.ENUM_ALL_PROP: 'EnumAllProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False),)), <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>: CommandInfo(name=<CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>: CommandInfo(name=<CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>, arguments=()), <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>: CommandInfo(name=<CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>, arguments=()), <CommandName.ENUM_PROP: 'EnumProp'>: CommandInfo(name=<CommandName.ENUM_PROP: 'EnumProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False),)), <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>: CommandInfo(name=<CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.ENUM_TOOLS: 'EnumTools'>: CommandInfo(name=<CommandName.ENUM_TOOLS: 'EnumTools'>, arguments=()), <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>: CommandInfo(name=<CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>, arguments=()), <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>: CommandInfo(name=<CommandName.FEATURE_EXTRACT: 'FeatureExtract'>, arguments=None), <CommandName.FIND_TOOL: 'FindTool'>: CommandInfo(name=<CommandName.FIND_TOOL: 'FindTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.FOUND_TOOL: 'FoundTool'>: CommandInfo(name=<CommandName.FOUND_TOOL: 'FoundTool'>, arguments=()), <CommandName.GET: 'Get'>: CommandInfo(name=<CommandName.GET: 'Get'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>: CommandInfo(name=<CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>: CommandInfo(name=<CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>, arguments=()), <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>: CommandInfo(name=<CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True),)), <CommandName.GET_DME_VERSION: 'GetDMEVersion'>: CommandInfo(name=<CommandName.GET_DME_VERSION: 'GetDMEVersion'>, arguments=()), <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>: CommandInfo(name=<CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>, arguments=()), <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>: CommandInfo(name=<CommandName.GET_ERROR_INFO: 'GetErrorInfo'>, arguments=(Parameter(name='ErrorNumber', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True),)), <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>: CommandInfo(name=<CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>, arguments=()), <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>: CommandInfo(name=<CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_PROP: 'GetProp'>: CommandInfo(name=<CommandName.GET_PROP: 'GetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_PROP_E: 'GetPropE'>: CommandInfo(name=<CommandName.GET_PROP_E: 'GetPropE'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>: CommandInfo(name=<CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>: CommandInfo(name=<CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>: CommandInfo(name=<CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>: CommandInfo(name=<CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>: CommandInfo(name=<CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>, arguments=(Parameter(name='CommandName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>: CommandInfo(name=<CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>, arguments=()), <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>: CommandInfo(name=<CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>, arguments=()), <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>: CommandInfo(name=<CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>, arguments=()), <CommandName.GO_TO: 'GoTo'>: CommandInfo(name=<CommandName.GO_TO: 'GoTo'>, arguments=(Parameter(name='Positions', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>: CommandInfo(name=<CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>: CommandInfo(name=<CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_PAR: 'GoToPar'>: CommandInfo(name=<CommandName.GO_TO_PAR: 'GoToPar'>, arguments=()), <CommandName.HOME: 'Home'>: CommandInfo(name=<CommandName.HOME: 'Home'>, arguments=()), <CommandName.IS_ALIGNABLE: 'IsAlignable'>: CommandInfo(name=<CommandName.IS_ALIGNABLE: 'IsAlignable'>, arguments=()), <CommandName.IS_HOMED: 'IsHomed'>: CommandInfo(name=<CommandName.IS_HOMED: 'IsHomed'>, arguments=()), <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>: CommandInfo(name=<CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>, arguments=()), <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>: CommandInfo(name=<CommandName.IS_USER_ENABLED: 'IsUserEnabled'>, arguments=()), <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>: CommandInfo(name=<CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.LOCK_AXIS: 'LockAxis'>: CommandInfo(name=<CommandName.LOCK_AXIS: 'LockAxis'>, arguments=(Parameter(name='Axis', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.LOCK_POSITION: 'LockPosition'>: CommandInfo(name=<CommandName.LOCK_POSITION: 'LockPosition'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>: CommandInfo(name=<CommandName.ON_MOVE_REPORT: 'OnMoveReport'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>: CommandInfo(name=<CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>: CommandInfo(name=<CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.ON_SCAN_REPORT: 'OnScanReport'>: CommandInfo(name=<CommandName.ON_SCAN_REPORT: 'OnScanReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>: CommandInfo(name=<CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.OPT_PAR: 'OptPar'>: CommandInfo(name=<CommandName.OPT_PAR: 'OptPar'>, arguments=()), <CommandName.PT_MEAS: 'PtMeas'>: CommandInfo(name=<CommandName.PT_MEAS: 'PtMeas'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.PT_MEAS_PAR: 'PtMeasPar'>: CommandInfo(name=<CommandName.PT_MEAS_PAR: 'PtMeasPar'>, arguments=()), <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>: CommandInfo(name=<CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>: CommandInfo(name=<CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.ROI: 'ROI'>: CommandInfo(name=<CommandName.ROI: 'ROI'>, arguments=None), <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>: CommandInfo(name=<CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>, arguments=(Parameter(name='RawDataFormat', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='Port', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), Parameter(name='LiveMode', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True))), <CommandName.RE_QUALIFY: 'ReQualify'>: CommandInfo(name=<CommandName.RE_QUALIFY: 'ReQualify'>, arguments=()), <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>: CommandInfo(name=<CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>, arguments=()), <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>: CommandInfo(name=<CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>: CommandInfo(name=<CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>: CommandInfo(name=<CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>: CommandInfo(name=<CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>: CommandInfo(name=<CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>: CommandInfo(name=<CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>: CommandInfo(name=<CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='d', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>: CommandInfo(name=<CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>: CommandInfo(name=<CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>: CommandInfo(name=<CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>: CommandInfo(name=<CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>, arguments=(Parameter(name='Displacement', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>: CommandInfo(name=<CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>, arguments=(Parameter(name=<ParameterName.CLOSED: 'Closed'>, datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=False), Parameter(name=<ParameterName.FORMAT: 'Format'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False), Parameter(name=<ParameterName.DATA: 'Data'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>: CommandInfo(name=<CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.AT_NOMINALS: 'AtNominals'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False))), <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>: CommandInfo(name=<CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>, arguments=(Parameter(name='Deviation', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>: CommandInfo(name=<CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pitch', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE: 'ScanOnLine'>: CommandInfo(name=<CommandName.SCAN_ON_LINE: 'ScanOnLine'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>: CommandInfo(name=<CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>, arguments=(Parameter(name='Angle', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_PAR: 'ScanPar'>: CommandInfo(name=<CommandName.SCAN_PAR: 'ScanPar'>, arguments=()), <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>: CommandInfo(name=<CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>: CommandInfo(name=<CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>, arguments=(Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True),)), <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>: CommandInfo(name=<CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True),)), <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>: CommandInfo(name=<CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SET_PROP: 'SetProp'>: CommandInfo(name=<CommandName.SET_PROP: 'SetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>: CommandInfo(name=<CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>, arguments=(Parameter(name='Temperatures', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>: CommandInfo(name=<CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>, arguments=(Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SET_TOOL: 'SetTool'>: CommandInfo(name=<CommandName.SET_TOOL: 'SetTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.START_SESSION: 'StartSession'>: CommandInfo(name=<CommandName.START_SESSION: 'StartSession'>, arguments=()), <CommandName.STEP: 'Step'>: CommandInfo(name=<CommandName.STEP: 'Step'>, arguments=(Parameter(name='Distances', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>: CommandInfo(name=<CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>, arguments=()), <CommandName.STOP_DAEMON: 'StopDaemon'>: CommandInfo(name=<CommandName.STOP_DAEMON: 'StopDaemon'>, arguments=(Parameter(name='EventTag', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True),)), <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>: CommandInfo(name=<CommandName.TILT_CENTER_PART: 'TiltCenterPart'>, arguments=(Parameter(name='Px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TILT_PART: 'TiltPart'>: CommandInfo(name=<CommandName.TILT_PART: 'TiltPart'>, arguments=(Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TOOL: 'Tool'>: CommandInfo(name=<CommandName.TOOL: 'Tool'>, arguments=()), <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>: CommandInfo(name=<CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>, arguments=()), 'UseSmallestAngleToAlignTool': CommandInfo(name='UseSmallestAngleToAlignTool', arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True),)), <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>: CommandInfo(name=<CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>, arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True),))})

The catalog of every command DEFAULT_COMMAND_CLASSES (every built-in simulated class) registers, keyed by command name.

Proprietary extension namespaces (6.1).

Any command, property, parameter, or attribute not defined by the standard must be prefixed with a two-character company-specific namespace when added by an implementation:

Example: Let a fictional company be abbreviated by XX. Proprietary commands are then named as: XXProprietaryCommandName(…) Properties, attributes, and parameters are named analogously, e.g.: GoTo(XXProprietaryParameter, …)

Nothing about a proprietary name is special at the wire-grammar level - it is an ordinary BasicName, so proprietary_name() is purely a naming-convention helper (and a place to catch the most common mistake, an empty or wrong-length namespace), not something the parser or server distinguishes from any other name. Use it both for command names (with register_proprietary()/ command_proprietary()) and, since the convention applies “analogously” to properties and parameters, when building a NamedValue for one of your own:

NamedValue(proprietary_name("XX", "ProprietaryParameter"), (Number.of(5),))
pyippdme.protocol.namespace.proprietary_name(namespace: str, name: str) → str

Build a spec-compliant proprietary command/property/parameter name.

namespace must be exactly two letters (6.1: “a company specific abbreviation having two characters”); name is the part specific to your extension, e.g. proprietary_name("XX", "ProprietaryCommandName") -> "XXProprietaryCommandName".

Per-command argument schemas backing GetSupportedArguments(CommandName) (6.4.1).

Each built-in command class declares a Parameter tuple per command, matching that command’s own “Parameters” table in the standard (one entry per top-level parameter - an enum parameter like GoTo’s Positions is one entry, not one per possible item inside it). The registry stores these alongside handlers (register()’s arguments keyword) so GetSupportedArguments can answer for real instead of always reporting “not supported”.

For the common case of a command whose arguments are a fixed, ordered list of plain numbers (the standard’s “Kind U” positional style, e.g. ScanOnLine(Sx, Sy, Sz, Ex, Ey, Ez, i, j, k, StepW, RT)), positional_float_parameters() builds that Parameter tuple and the (min_count, max_count) bounds positional_numbers() needs to validate the call - from the same list of names, so the advertised schema and the enforced argument count cannot drift apart. Commands whose arguments are richer (an enum, a named property lookup, …) still validate by hand in their own handler, since their per-item structure is beyond what the six datatypes (Table 2: bool, int, float, string, enum, name) can express at this granularity - GetSupportedArguments() only ever describes top-level parameters, not what belongs inside an enum.

class pyippdme.protocol.signature.DataType(*values)

Table 2’s six wire datatypes for a command/property argument.

class pyippdme.protocol.signature.Parameter(name: str, datatype: DataType, mandatory: bool = True, positional: bool = False)

One top-level parameter of a command, as the standard’s own tables define it.

positional is not part of that wire schema at all (GetSupportedArguments only ever reports name/datatype - see _get_supported_arguments()) - it is local, descriptive metadata for tooling built on this same catalog (the TUI’s argument completion and .help; see pyippdme.cli.tui), marking whether the call itself writes this argument as a bare value rather than as a Name(value) pair like GoTo(X(10), Sync(1)). Two distinct shapes share this flag: a fixed, ordered list of several bare values (the standard’s “Kind U” style, e.g. ScanOnLine(1, 2, 3, ...) - see positional_float_parameters()), and a single command whose lone argument just isn’t named in its call at all (e.g. GetErrorInfo(506), not GetErrorInfo(ErrorNumber(506))). Neither is derivable from datatype/parameter count alone - whether a given command uses this shape has to be read off its handler; see tests/test_supported_arguments.py’s test_every_positional_command_matches_this_audit for the full, by-hand-audited list this flag encodes.

pyippdme.protocol.signature.positional_float_parameters(*names: str, optional: tuple[str, ...] = ()) → tuple[Parameter, ...]

Build the Parameter tuple for a fixed, ordered list of float arguments.

optional names (if any) must be the trailing entries of names, matching how every such command in this project (ScanOnLine’s RT, etc.) puts its one optional argument last. Every Parameter this builds has positional=True - see Parameter.

pyippdme.protocol.signature.argument_count_bounds(parameters: tuple[Parameter, ...]) → tuple[int, int]

Return the (min_count, max_count) bounds for positional_numbers to enforce.

See positional_numbers().

Where connections come from: TCP, or an in-process network.

The I++ DME protocol itself runs over TCP (5.1). Everything in this package that opens or accepts a connection (IppDmeClient, IppDmeServer, Spy, the raw-data binary socket) does so through a Network, which mirrors asyncio.open_connection() and asyncio.start_server().

TCP_NETWORK is the default. A MemoryNetwork keeps every connection inside the process, so a server and its clients can talk without opening a port:

network = MemoryNetwork()
server = VirtualCMM(network=network)
port = await server.start()
client = await IppDmeClient.connect("virtual", port, network=network)

Host names are ignored by a MemoryNetwork; connections are matched by port only.

class pyippdme.protocol.network.StreamReaderLike(*args, **kwargs)

The part of asyncio.StreamReader this package uses.

class pyippdme.protocol.network.StreamWriterLike(*args, **kwargs)

The part of asyncio.StreamWriter this package uses.

pyippdme.protocol.network.DEFAULT_LIMIT = 65536

asyncio’s own default stream buffer size.

class pyippdme.protocol.network.Listener(*args, **kwargs)

A bound server endpoint returned by Network.start_server().

class pyippdme.protocol.network.Network(*args, **kwargs)

Opens outgoing and accepts incoming byte-stream connections.

async open_connection(host: str, port: int, *, limit: int = 65536) → tuple[StreamReaderLike, StreamWriterLike]

Connect to host:port; raise OSError if nothing is listening.

async start_server(on_client: Callable[[StreamReaderLike, StreamWriterLike], Awaitable[None]], host: str, port: int, *, limit: int = 65536) → Listener

Listen on host:port; port=0 picks a free one (see Listener.port).

class pyippdme.protocol.network.TcpNetwork

Real TCP sockets, via asyncio.

class pyippdme.protocol.network.MemoryNetwork

Connections that stay inside the process: no sockets, no ports opened.

Each instance is its own isolated network. Ports are plain numbers scoped to the instance; hosts are ignored.

The pluggable interface between command handlers and real hardware.

Handlers for commands that just report or mutate protocol-level state (the active coordinate system, a property store, session/error bookkeeping) work directly against MachineState and need no backend. Handlers for commands that move or measure a real machine delegate that part to a MachineBackend, so a server integrator can swap in real hardware control without touching argument parsing, validation, or response encoding: pass your own object satisfying this Protocol (no inheritance required - it’s structural) to IppDmeServer(backend=...). This module holds only the interface itself - the concrete, simulated implementation (SimulatedBackend) lives in pyippdme.simulation, which depends on this module, not the other way around.

Currently only the Scanning class subset (pyippdme.simulation.classes.scanning_class) goes through a backend; other classes still hold their (simpler, instantaneous) state directly on MachineState. The same pattern extends to them the same way, by adding a method here and delegating to it from the handler. Argument validation (degenerate geometry, orthogonality, …) stays in the handler, which runs before the backend is invoked at all: a backend only ever sees geometry already known to be well-formed.

pyippdme.server.backend.CancellationToken

Signalled (via .set()) when a running operation must stop as soon as possible, e.g. because the client sent AbortE(). A backend method should check it cooperatively between physical steps (and, if it wraps a blocking SDK in an executor thread, pass it - or an equivalent signal - into that thread) rather than relying solely on asyncio.Task cancel: cancelling the task only stops the coroutine from being awaited, it does not by itself stop a blocking call already running in another thread.

class pyippdme.server.backend.MachineBackend(*args, **kwargs)

Physical operations behind the Scanning command subset.

Every method is an async generator: implementations should yield each point as soon as it is actually acquired (matching 6.13.2’s “already measured data may be transmitted… while execution… is still in progress”), and return early - after any hardware-specific cleanup, e.g. stopping motion - once cancel is set.

class pyippdme.server.backend.ContourBackend(*args, **kwargs)

Optional part of a MachineBackend: follow the real surface of a part.

For the five unknown-contour scans (6.13.2.2, Figures 35-39). See pyippdme.server.contour for the request and trace_contour() for an algorithm that follows a surface given a function that probes it. Without it those scans fall back to a straight line towards their stop element.

The default, simulated MachineBackend.

No real hardware, only geometry - see pyippdme.server.backend for the Protocol this implements and why a real integrator would supply their own instead.

class pyippdme.simulation.backend.SimulatedBackend(*, step_delay: float = 0.01)

The default backend: no real hardware, only geometry.

Points are yielded one at a time with a small delay between them, both to resemble real (non-instantaneous) motion and so that cancellation via AbortE() has something observable to interrupt in tests and demos.

async scan_helix(center: tuple[float, float, float], start: tuple[float, float, float], normal: tuple[float, float, float], delta_deg: float, step_w_deg: float, pitch: float, cancel: Event) → AsyncIterator[tuple[float, float, float]]

Follow scan_circle()’s path, adding a pitch-per-turn rise along normal.

The pluggable interface between PtMeas and a real (or synthetic) part.

Without a surface, PtMeas (6.12.1) simply reports whatever position the client commanded - there is nothing for the probe to actually touch, so approach/search/retract distances and the IJK probing direction are accepted but have no effect (see pyippdme.simulation.classes.cartcmm_class’s module docstring). SampleSurface is the seam that changes that: a IppDmeServer/VirtualCMM configured with one gets a real, if synthetic, part for PtMeas to measure against - a measured point can genuinely diverge from the commanded one, and “no surface found” becomes a real, reachable error (1006) instead of something that can never happen. This module holds only the interface itself - the concrete geometry (planes, spheres, cylinders) lives in pyippdme.simulation.surface, which depends on this module, not the other way around; a real integrator with an actual CAD/mesh representation of the part implements this same one-method Protocol directly instead.

class pyippdme.server.surface.SampleSurface(*args, **kwargs)

A synthetic surface a probing ray can intersect (structural - no inheritance needed).

direction need not be normalized. Returns the nearest intersection point with t >= 0 along direction from origin, or None if the ray never meets the surface (including when the surface is entirely behind origin). Implementations don’t need to know or care how far the caller intends to search - that bound is applied by the caller (pyippdme.simulation.classes.cartcmm_class), against Tool/Part’s Approach/Search properties.

class pyippdme.server.surface.RawSensor(*args, **kwargs)

A simulated optical/laser sensor that answers DataAcquire (6.15.1).

Without one, DataAcquire synthesizes points from the requested positions alone. With one, the sensor decides what it sees: positions and directions are the control points the client sent (one per n; a single TCP position for n == 0), acquisition_type is SingleShot, MultiShot or Sweep. Return None to fall back to the built-in synthesis.

Synthetic sample-surface geometry: concrete SampleSurfaces.

This is also the intended extension point for a future “load a CAD mesh as the sample” GUI feature - that surface would satisfy the same one-method Protocol as the three simple ones here (see pyippdme.server.surface).

class pyippdme.simulation.surface.PlaneSurface(point: tuple[float, float, float], normal: tuple[float, float, float])

An infinite flat plane through point, perpendicular to normal.

class pyippdme.simulation.surface.SphereSurface(center: tuple[float, float, float], radius: float)

A sphere centered at center with the given radius (mm).

class pyippdme.simulation.surface.CylinderSurface(point: tuple[float, float, float], axis: tuple[float, float, float], radius: float)

An infinite cylinder of the given radius (mm).

Centered on the line through point along axis.

class pyippdme.simulation.surface.CompositeSurface(surfaces: list[SampleSurface])

Several surfaces as one: a probing ray meets the nearest of them.

pyippdme.simulation.surface.parse_surface(spec: str) → SampleSurface

Parse plane:px,py,pz:nx,ny,nz, sphere:cx,cy,cz:r or cylinder:p:a:r.

Coordinate-system transformation math and persistence (6.5.1/6.5.2).

A CartCMM defines several coordinate systems (CSYs) that sit below the base MachineCsy in a transformation chain (MachineCsy -> … -> PartCsy, 6.5.1, Figure 12 - not reproduced here, it is a diagram). The transformation from a parent CSY to a child one is a rigid motion: a proper Euler-angle rotation (angles Phi, Theta, Psi about axes Z, X’, Z’’ respectively, in that composition order) followed by a translation, i.e. p_parent = R(Phi, Theta, Psi) @ p_child + t.

This module provides that transform as a reusable, tested building block (CoordinateTransform) plus a pluggable persistence seam (CsyStore, mirroring MachineBackend) for the named coordinate systems SaveNamedCsyTransformation/ LoadCoordSystem and friends require to survive “in another session and after rebooting” (6.5.2).

Scope note: pyippdme.simulation.classes.cartcmm_class’s command handlers store and return these transforms faithfully, but the minimal simulated Get/GoTo handlers do not apply them to convert reported/commanded coordinates between CSYs: they have no machine coordinates to convert to. The chain across the CSYs is defined by Figure 12 (a diagram this library cannot extract from the PDF); this module commits to one reading of it, CSY_CHAIN and chain_matrix(), which pyippdme.twin applies. A machine with a different chain can compose its own with CoordinateTransform.apply().

pyippdme.types.csy.LIVE_TRANSFORM_NAMES = ('PartCsy', 'JogDisplayCsy', 'JogMoveCsy', 'SensorCsy', 'MoveableMachineCsy', 'MultipleArmCsy', 'RotaryTableFixCsy')

The CSY names SetCsyTransformation/GetCsyTransformation accept (6.5.2, Tables 35/38): child CSYs whose transformation relative to their parent in the chain can be queried/replaced live, for the current connection only.

pyippdme.types.csy.CSY_CHAIN = ('MachineCsy', 'MultipleArmCsy', 'MoveableMachineCsy', 'RotaryTableFixCsy', 'RotaryTableVarCsy', 'PartCsy')

The transformation chain of a CartCMM (6.5.1, Figure 12), from the machine to the part. Coordinates of PartCsy pass through RotaryTableVarCsy, RotaryTableFixCsy, MoveableMachineCsy and MultipleArmCsy into MachineCsy. Each CSY is placed relative to the one before it in this tuple with SetCsyTransformation (6.5.2), and SetCoordSystem chooses where a client enters the chain. The offset of the tool is included in all of them. RotaryTableVarCsy and MoveableMachineCsy are in the figure for consistency (the rotary table’s angle and movable measuring equipment).

class pyippdme.types.csy.CoordinateTransform(x0: float, y0: float, z0: float, theta: float, psi: float, phi: float)

A rigid transform from a parent CSY to a child CSY (6.5.1).

psi/phi are normalized modulo 360 on construction, per 6.5.2’s “Psi and Phi are unlimited but ‘normalized’ by the server (modulo 360)”. theta is left as given; callers enforce its [0, 180] range (error 1007 “Theta out of range”) since only they know whether that should be a hard rejection or a silent clamp.

rotation_matrix() → NDArray[float64]

Return the rotation from child to parent coordinates: Rz(Psi) @ Rx(Theta) @ Rz(Phi).

The standard (6.5.1, Figure 12 text) defines the transformation from the parent to the child CSY as p' = R(phi, theta, psi) . (p - t) with:

R = [[ cos phi, sin phi, 0], [-sin phi, cos phi, 0], [0, 0, 1]]
  . [[1, 0, 0], [0, cos theta, sin theta], [0, -sin theta, cos theta]]
  . [[ cos psi, sin psi, 0], [-sin psi, cos psi, 0], [0, 0, 1]]

Those are rotations of the axes (the transpose of the usual rotation matrices), so the child-to-parent direction this method returns is the transpose of R, which is Rz(psi) Rx(theta) Rz(phi) in the usual notation (phi and psi swap places).

parent_to_child(point: tuple[float, float, float]) → tuple[float, float, float]

Transform point from the parent CSY into the child CSY: R . (p - t) (6.5.1).

apply(point: tuple[float, float, float]) → tuple[float, float, float]

Transform point from the child CSY into the parent CSY: R @ p + t.

inverse() → CoordinateTransform

Compute the transform from the parent CSY back to the child CSY.

pyippdme.types.csy.transform_matrix(transform: CoordinateTransform) → NDArray[float64]

Return the 4x4 homogeneous matrix of transform (child to parent coordinates).

pyippdme.types.csy.chain_matrix(active: str, transforms: Mapping[str, CoordinateTransform], rotary_var: NDArray[float64] | None = None) → NDArray[float64]

Return the 4x4 matrix that maps points of the active CSY into MachineCsy.

transforms holds the live transformations of the CSYs of CSY_CHAIN by name (a CSY without one is placed at its parent). RotaryTableVarCsy is not set by a command but follows the rotary table: pass its 4x4 matrix as rotary_var, or None while that calculation is not enabled. An unknown active name (MachineCsy included) is the identity.

class pyippdme.types.csy.CsyContext(active: str = 'MachineCsy', transforms: Mapping[str, ~pyippdme.types.csy.CoordinateTransform]=<factory>, rotary_var: NDArray[float64] | None = None)

The coordinate system a client works in, and how it sits in the machine (6.5.1, 6.5.2).

This is what a server needs to turn the coordinates of a command into machine coordinates and a result back into the client’s: the CSY the client activated with SetCoordSystem, the live transformations it set with SetCsyTransformation and LoadCoordSystem (by CSY name, each relative to the one before it in CSY_CHAIN), and, while the rotary table’s own system is calculated, that system’s 4x4 matrix:

context = CsyContext("PartCsy", {"PartCsy": CoordinateTransform(100, 0, 0, 0, 0, 90)})
machine_point = context.to_machine((10, 0, 0))
client_point = context.to_client(machine_point)
probing = context.direction_to_machine((0, 0, 1))   # IJK, tool axis: rotation only

Points and directions are separate because a direction is not moved by a translation.

rotary_var: NDArray[float64] | None

Matrix of RotaryTableVarCsy (the rotary table’s angle) while it is calculated.

matrix() → NDArray[float64]

Return the 4x4 matrix mapping the active CSY into MachineCsy.

to_machine(point: tuple[float, float, float]) → tuple[float, float, float]

Convert a point of the active CSY to machine coordinates.

to_client(point: tuple[float, float, float]) → tuple[float, float, float]

Convert a machine point to the active CSY.

direction_to_machine(vector: tuple[float, float, float]) → tuple[float, float, float]

Convert a direction of the active CSY to machine coordinates (rotation only).

direction_to_client(vector: tuple[float, float, float]) → tuple[float, float, float]

Convert a machine direction to the active CSY (rotation only).

class pyippdme.types.csy.CsyStore(*args, **kwargs)

Pluggable persistence for named coordinate systems (6.5.2 “stored persistently”).

Mirrors MachineBackend: IppDmeServer defaults to InMemoryCsyStore (matching its default of SimulatedBackend - no surprise disk I/O out of the box), and a real deployment that needs the standard’s persistence guarantee passes a FileCsyStore (or its own implementation, e.g. backed by a database) explicitly.

async delete(name: str) → bool

Delete name; return whether it existed.

class pyippdme.types.csy.InMemoryCsyStore

A CsyStore that only lasts for the process lifetime.

class pyippdme.types.csy.FileCsyStore(directory: Path | None = None)

A CsyStore that persists each named transform as a JSON file.

Name is client-controlled (wire type [string], so it may contain / or ..); _path_for() rejects anything that is not a plain file-safe name rather than trusting it as a path component.

The Tool parameter-block mechanism (6.10.4 “Parameter sets of class Tool”).

GoToPar/PtMeasPar/ScanPar are property blocks addressed through Tool (e.g. GetProp(Tool.PtMeasPar.Retract())) even though, per 6.10.4, they conceptually belong to other classes (Tool, TouchTrigger, Scanning respectively). Each individual parameter has four values - Min, Max, Def and Act - of which only Act is client settable, clamped into [Min, Max] with warning 0504 if the client’s value falls outside it (6.10.4). .Act() may be omitted, i.e. Tool.PtMeasPar.Retract() and Tool.PtMeasPar.Retract.Act() refer to the same value.

This module holds only the mechanism itself - a bare ToolParameters starts with empty blocks, no Min/Max/Def numbers of its own, since the standard leaves those to each tool’s qualification. See pyippdme.simulation.tool for this library’s own bundled simulation’s plausible defaults.

class pyippdme.server.tool.ParameterField(*values)

Sub-property suffixes accepted after a parameter name, e.g. Retract.Min().

pyippdme.server.tool.PARAMETER_FIELDS = (ParameterField.MIN, ParameterField.MAX, ParameterField.DEF, ParameterField.ACT)

Every ParameterField, in the order 6.10.4 lists them.

class pyippdme.server.tool.ToolParameter(minimum: float, maximum: float, default: float, act: float | None = None)

One physical value of a parameter set, with the Min/Max/Def/Act model.

property value: float

The effective (Act, or Def if Act was never set) value.

set_act(value: float) → bool

Clamp value into [minimum, maximum] and store it as Act.

Returns whether clamping changed the value (the caller should then raise warning 0504 “Argument out of range”).

class pyippdme.server.tool.ToolParameters(go_to_par: dict[str, ~pyippdme.server.tool.ToolParameter]=<factory>, pt_meas_par: dict[str, ~pyippdme.server.tool.ToolParameter]=<factory>, scan_par: dict[str, ~pyippdme.server.tool.ToolParameter]=<factory>)

All GoToPar/PtMeasPar/ScanPar parameter blocks of the active tool.

Starts with every block empty - see the module docstring for why no Min/Max/Def numbers are built in here.

This library’s own plausible Tool parameter-block defaults (6.10.4).

The Min/Max/Def values below are this library’s own simulation defaults (plausible values for a small tactile CMM), not numbers the standard mandates - see pyippdme.server.tool for the mechanism itself (Min/Max/Def/Act clamping semantics), which has no such numbers built in.

Tool.Id() XML payload (Annex G, referenced by 6.10.3 Id()).

The schema (src/pyippdme/schemas/Tool_ID.xsd) models a tool description document rooted at <toolID>, wrapping exactly one of six concrete tool types: two tactile (toolTactileTouchTrigger, toolTactileMeasuring, both plain extensions of the abstract tool/toolTactile base with no extra fields) and four optical (toolOptical1D, toolOptical2D-rs, toolOptical2D-rt, toolOptical3D, each adding livestream/binary-socket support flags, data-acquisition function descriptions, and a region of interest appropriate to their dimensionality).

Region-of-interest elements (line, polygon2D, circle, circleRel, polygon3D, sphere, sphereRel, cylinder, cylinderRel) all extend the abstract ROI type without adding fields of their own in this schema, so a single Roi models all nine, with kind recording which element name wrapped it.

pyippdme.types.tool_id.BASIC_FUNCTIONS = ('GoTo', 'PtMeas', 'ScanOnPlane', 'ScanOnLine', 'ScanOnCircle', 'ScanOnHelix', 'ScanOnCurve', 'PTMeasSelfCenter', 'PTMeasSelfCenterLocked', 'DataAcquire', 'DeleteAcquisition', 'DeleteAllAcquisition', 'FeatureExtract', 'GetRawDataBin', 'GetRawDataShaMem', 'ReleaseShaMem')

The 16 enumerated basicfunction values (Annex G).

pyippdme.types.tool_id.CNC_AXES = ('X', 'Y', 'Z', 'A', 'B', 'C', 'R')

The 7 enumerated cnc_axis values (Annex G).

pyippdme.types.tool_id.ROI_KINDS = ('line', 'polygon2D', 'circle', 'circleRel', 'polygon3D', 'sphere', 'sphereRel', 'cylinder', 'cylinderRel')

The 9 concrete ROI element names a <roi> may wrap.

class pyippdme.types.tool_id.FixedAlignMode

<alignmode_fixed/>: the tool’s orientation cannot be changed.

class pyippdme.types.tool_id.IndexedAlignMode(aligncaa: bool, step: float)

<alignmode_indexed>: orientation changes in discrete steps.

class pyippdme.types.tool_id.ContinuousAlignMode(aligncaa: bool)

<alignmode_continuous>: orientation changes continuously.

class pyippdme.types.tool_id.DataAcquisitionFunction(size_x: float | None = None, size_y: float | None = None, size_z: float | None = None)

dataAcquisition: the field-of-view size of a data-acquisition function.

class pyippdme.types.tool_id.DataAcquisitionFunctions(single_shot: DataAcquisitionFunction | None = None, multi_shot: DataAcquisitionFunction | None = None, sweep: DataAcquisitionFunction | None = None)

Which of SingleShot/MultiShot/Sweep acquisition an optical tool supports.

class pyippdme.types.tool_id.Roi(kind: str, name: str, roi_type: str, include: bool)

A region of interest; see the module docstring for kind.

class pyippdme.types.tool_id.ToolId(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: FixedAlignMode | IndexedAlignMode | ContinuousAlignMode, move_on_acquisition: bool)

Fields common to every tool type (the abstract tool complex type).

class pyippdme.types.tool_id.ToolIdTactileTouchTrigger(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: FixedAlignMode | IndexedAlignMode | ContinuousAlignMode, move_on_acquisition: bool)

A tactile TouchTrigger tool (toolTactileTouchTrigger); adds no fields.

class pyippdme.types.tool_id.ToolIdTactileMeasuring(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: FixedAlignMode | IndexedAlignMode | ContinuousAlignMode, move_on_acquisition: bool)

A tactile measuring (analog/scanning) tool (toolTactileMeasuring); adds no fields.

class pyippdme.types.tool_id.ToolIdOptical(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: ~pyippdme.types.tool_id.FixedAlignMode | ~pyippdme.types.tool_id.IndexedAlignMode | ~pyippdme.types.tool_id.ContinuousAlignMode, move_on_acquisition: bool, supports_livestream: bool = False, supports_binary_socket: bool = False, daq_functions: ~pyippdme.types.tool_id.DataAcquisitionFunctions = <factory>)

Fields common to every optical tool type.

class pyippdme.types.tool_id.ToolIdOptical1D(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: ~pyippdme.types.tool_id.FixedAlignMode | ~pyippdme.types.tool_id.IndexedAlignMode | ~pyippdme.types.tool_id.ContinuousAlignMode, move_on_acquisition: bool, supports_livestream: bool = False, supports_binary_socket: bool = False, daq_functions: ~pyippdme.types.tool_id.DataAcquisitionFunctions = <factory>, roi: ~pyippdme.types.tool_id.Roi | None = None)

A 1D optical tool (toolOptical1D), e.g. a laser line/point sensor.

class pyippdme.types.tool_id.ToolIdOptical2DRs(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: ~pyippdme.types.tool_id.FixedAlignMode | ~pyippdme.types.tool_id.IndexedAlignMode | ~pyippdme.types.tool_id.ContinuousAlignMode, move_on_acquisition: bool, supports_livestream: bool = False, supports_binary_socket: bool = False, daq_functions: ~pyippdme.types.tool_id.DataAcquisitionFunctions = <factory>, roi: ~pyippdme.types.tool_id.Roi | None = None)

A 2D optical tool with rectangular sampling (toolOptical2D-rs).

class pyippdme.types.tool_id.ToolIdOptical2DRt(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: ~pyippdme.types.tool_id.FixedAlignMode | ~pyippdme.types.tool_id.IndexedAlignMode | ~pyippdme.types.tool_id.ContinuousAlignMode, move_on_acquisition: bool, supports_livestream: bool = False, supports_binary_socket: bool = False, daq_functions: ~pyippdme.types.tool_id.DataAcquisitionFunctions = <factory>, roi: ~pyippdme.types.tool_id.Roi | None = None)

A 2D optical tool with rotational sampling (toolOptical2D-rt).

class pyippdme.types.tool_id.ToolIdOptical3D(id: str, basic_functions: tuple[str, ...], cnc_axes: tuple[str, ...], supports_optimization_mode: bool, align_mode: ~pyippdme.types.tool_id.FixedAlignMode | ~pyippdme.types.tool_id.IndexedAlignMode | ~pyippdme.types.tool_id.ContinuousAlignMode, move_on_acquisition: bool, supports_livestream: bool = False, supports_binary_socket: bool = False, daq_functions: ~pyippdme.types.tool_id.DataAcquisitionFunctions = <factory>, roi: ~pyippdme.types.tool_id.Roi | None = None)

A 3D optical tool (toolOptical3D), e.g. a structured-light/laser scanner.

pyippdme.types.tool_id.to_xml(tool: ToolId) → str

Serialize tool as a <toolID> document (Annex G).

pyippdme.types.tool_id.from_xml(text: str) → ToolId

Parse a <toolID> document (Annex G) back into a ToolId.

May carry data from an untrusted remote peer, so uses defusedxml.

Raw point-cloud XML payload (Annex E, referenced by 6.17.1).

A PointCloudSet holds one or more PointCloud``s (e.g. one per scan pass); each ``PointCloud holds one or more PointSet``s (Mx/My/Mz is a surface normal, I/J/K a scan/measurement direction, both shared by every point in the set); each ``PointSet holds one or more MeasPoint``s (X/Y/Z plus a quality byte ``Q, c.f. the Q() property).

class pyippdme.types.pointcloud.MeasPoint(x: float, y: float, z: float, q: int)

A single measured point: X()/Y()/Z() plus a quality byte Q().

class pyippdme.types.pointcloud.PointSet(normal: tuple[float, float, float], direction: tuple[float, float, float], points: tuple[MeasPoint, ...])

A set of measuring points sharing one surface normal and scan direction.

class pyippdme.types.pointcloud.PointCloud(point_sets: tuple[PointSet, ...])

A single point cloud: one or more PointSet.

class pyippdme.types.pointcloud.PointCloudSet(point_clouds: tuple[PointCloud, ...])

A set of point clouds, e.g. one per scan pass.

pyippdme.types.pointcloud.from_xml(text: str) → PointCloudSet

Parse text; may carry data from an untrusted remote peer, so uses defusedxml.

Tool.AdvDataStruct() XML payload (Annex F, referenced by 6.17.2).

Describes how a server will hand over raw sensor data: through which technology (SocBin a binary socket, ShaMem shared memory, File a file on disk - one or more may be offered at once) and in which format, either a generic structured sample (Gen) or one of the simple, opaque formats (BitMap/Jpeg/SBF/ESBF/XML).

pyippdme.types.rawdata.RETURN_TECHNOLOGIES = ('SocBin', 'ShaMem', 'File')

The technologies through which raw data may be retrieved (6.17.2).

pyippdme.types.rawdata.SIMPLE_FORMATS = ('BitMap', 'Jpeg', 'SBF', 'ESBF', 'XML')

The format kinds that carry no further structure of their own.

class pyippdme.types.rawdata.Vector(x: float, y: float, z: float)

A 3D vector as used in Tool.AdvDataStruct() (Annex F).

class pyippdme.types.rawdata.PosInformation(tcp: Vector, ijk: Vector | None = None, lmn: Vector | None = None)

Which position/orientation vectors accompany each sample.

class pyippdme.types.rawdata.PixelStructure(bits_per_color_channel: int, num_color_channels: int)

How each sample’s color/intensity channels are encoded.

class pyippdme.types.rawdata.DimensionSample(span_wp: float, no_pixel_of_dim: int)

One dimension’s SpanWP/NoPixelOfDim pair of a SampleStructure.

class pyippdme.types.rawdata.SampleStructure(dimensions: tuple[DimensionSample, ...])

The dimensionality and per-dimension extent of a generic sample.

class pyippdme.types.rawdata.GenFormat(pos_information: PosInformation, pixel_structure: PixelStructure, sample_structure: SampleStructure)

The generic, structured sample format (as opposed to an opaque image/binary format).

pyippdme.types.rawdata.Format = pyippdme.types.rawdata.GenFormat | str

Either the structured Gen format, or one of SIMPLE_FORMATS by name.

class pyippdme.types.rawdata.AdvDataStruct(return_technologies: frozenset[str], format: GenFormat | str)

How a server will hand over raw sensor data (Tool.AdvDataStruct()).

pyippdme.types.rawdata.from_xml(text: str) → AdvDataStruct

Parse text; may carry data from an untrusted remote peer, so uses defusedxml.

Raw-data transfer mechanics (6.17.2): binary socket, shared memory, and file.

See pyippdme.simulation.classes.rawdata_class for the command handlers that call into this.

The Scanpoints Binary Format (SBF) and its extension ESBF (Annex C).

Both formats hold point groups, each made of point sets, each made of points, little-endian, after a 512-byte header. SBF stores float (4 byte) values only. ESBF adds the choice between float and double (8 byte), and lets a group of point sets be sent without knowing their number in advance (C.2): a set with zero points ends the group.

Invalid points are marked with the largest value of the data type in all three coordinates; they are NaN once read here, and written as that value.

pyippdme.rawdata.formats.IDENTIFIER = b'IDME'

The identifier every file starts with.

pyippdme.rawdata.formats.VERSION = 0

The only version defined (Annex C).

pyippdme.rawdata.formats.DESCRIPTION_LENGTH = 128

Length of the descriptive text in the header.

class pyippdme.rawdata.formats.PointSetData(orientation: tuple[float, float, float], points: NDArray[float64])

The points of one set and the scan orientation vector that applies to all of them.

class pyippdme.rawdata.formats.ScanData(groups: tuple[tuple[PointSetData, ...], ...], description: str = '', normal_direction: int = 0, data_format: str = 'float')

The content of an SBF or ESBF stream: point groups made of point sets.

data_format: str

what the stream stored the values as.

Type:

"float" or "double"

points() → NDArray[float64]

All points of all sets, one row per point.

pyippdme.rawdata.formats.pack_sbf(groups: tuple[tuple[PointSetData, ...], ...], *, description: str = '', normal_direction: int = 0) → bytes

Write groups as an SBF stream (C.1).

pyippdme.rawdata.formats.pack_esbf(groups: tuple[tuple[PointSetData, ...], ...], data_format: str = 'float', *, description: str = '', normal_direction: int = 0, counted: bool = True) → bytes

Write groups as an ESBF stream (C.2).

With counted=False the number of point sets is not given and each group ends with an empty point set instead, as when the data is sent while it is acquired (LiveMode(On), 6.17.2.1).

pyippdme.rawdata.formats.unpack_sbf(payload: bytes) → ScanData

Read an SBF stream (C.1).

pyippdme.rawdata.formats.unpack_esbf(payload: bytes) → ScanData

Read an ESBF stream (C.2), including one sent without counting its point sets.

The three same-machine/cross-machine raw-data transfer mechanics (6.17.2).

Each function here implements one of the transfer technologies AdvDataStruct.ReturnTechnology can advertise (pyippdme.types.rawdata): a binary TCP socket (6.17.2.1), OS shared memory (6.17.2.2, via the standard library’s cross-platform multiprocessing.shared_memory, so it works unmodified on both Linux and Windows), and a plain file (6.17.2.3). All three carry a PointCloudSet as an ESBF stream (Annex C.2, pyippdme.rawdata.formats) of float or double values, little-endian (“Intel format”, 6.17.2.1).

pyippdme.rawdata.transfer.BIN_SOCKET_ACCEPT_TIMEOUT = 30.0

How long a binary-socket listener waits for the client to connect before giving up (this is a reference/simulated implementation, not a tuned production default).

pyippdme.rawdata.transfer.point_groups(data: PointCloudSet) → tuple[tuple[PointSetData, ...], ...]

Turn the point clouds into SBF/ESBF point groups: one group per cloud, one set per set.

pyippdme.rawdata.transfer.esbf_payload(data: PointCloudSet, data_format: str, *, counted: bool = True) → bytes

Serialize data as an ESBF stream (Annex C.2), the format all transfers here use.

async pyippdme.rawdata.transfer.read_samples(host: str, port: int, data_format: str, *, network: Network = <pyippdme.protocol.network.TcpNetwork object>, timeout: float = 5.0) → NDArray[float64]

Connect to a server’s raw-data port, read until it closes, and return all points.

The stream is ESBF (Annex C.2); data_format is what RawDataBinSetup asked for and is checked against the stream’s own header. The server only listens while a GetRawDataBin is running, so connection attempts are retried until timeout seconds have passed.

async pyippdme.rawdata.transfer.read_scan_data(host: str, port: int, *, network: Network = <pyippdme.protocol.network.TcpNetwork object>, timeout: float = 5.0) → ScanData

Like read_samples(), but return the point groups and sets of the ESBF stream.

async pyippdme.rawdata.transfer.send_once(host: str, port: int, payload: bytes, *, network: Network = <pyippdme.protocol.network.TcpNetwork object>) → None

Listen on (host, port), accept exactly one connection, write payload, close.

Bounded by BIN_SOCKET_ACCEPT_TIMEOUT so a client that never connects cannot leak the listener forever. A fresh listener is opened per call (rather than kept alive from RawDataBinSetup), since only one client connection is ever expected per acquisition retrieval.

pyippdme.rawdata.transfer.publish_shared_memory(payload: bytes) → SharedMemory

Create an OS shared-memory segment containing payload at offset 0.

pyippdme.rawdata.transfer.write_raw_data_file(directory: Path, acq_name: str, payload: bytes, suffix: str) → Path

Write payload to a file under directory, named after acq_name.

The five conformance classes of Annex J.1 (deprecated).

A conformance class names the object-model components a typical machine has. The standard deprecated the concept: a server’s capabilities are found with GetSupportedCommands() and GetSupportedArguments(..) instead (4.3, Annex K).

class pyippdme.protocol.conformance.ConformanceClass(description: str, tool: str, align_mode: str, mover: str | None = None, rotary_table: str | None = None, cart_cmm: str = 'CartCMM', tool_changer: str = 'ToolChanger')

One conformance class: the classes of the machine’s components (Annex J.1).

property machine_class: str

The GetMachineClass() string of a machine of this class (6.4.1).

Minimal 3D vector helpers, shared across command handlers and the backend.

Vec3 stays a plain (x, y, z) tuple at the public boundary (it is part of MachineBackend, so implementers should not need numpy just to yield a point), but the arithmetic itself is delegated to numpy rather than hand-rolled, since numpy is already a dependency for pyippdme.types.csy’s rotation matrices.

pyippdme.types.vec3.to_array(v: tuple[float, float, float]) → NDArray[float64]

Convert to a numpy array, for callers doing more than a single operation.

Client-side transaction bookkeeping (5.4.3, 5.5).

class pyippdme.client.transaction.Transaction(tag: Tag | EventTag, _acked: Event = <factory>, _completed: Event = <factory>, _error: ServerError | None = None, _connection_error: IppDmeConnectionError | None = None, _data: list[NumericData | PropertyData | Items | StringValue | NameValue | Xml] = <factory>, _incoming: Queue[NumericData | PropertyData | Items | StringValue | NameValue | Xml | None] = <factory>, _events: Queue[NumericData | PropertyData | Items | StringValue | NameValue | Xml | None] = <factory>)

Tracks one client-initiated transaction from Ack through Done.

A transaction started with an EventTag (e.g. an OnMoveReportE(...) daemon) keeps delivering data through events() after wait_complete() returns, for as long as the daemon runs; a plain-Tag transaction collects all of its data up front and is done once wait_complete() returns.

property received_data: bool

Whether any data response arrived before the transaction completed.

async wait_ack() → None

Wait for the acknowledgement response, raising if it was an error.

async wait_complete() → tuple[NumericData | PropertyData | Items | StringValue | NameValue | Xml, ...]

Wait for the transaction-complete response and return the data collected so far.

async stream() → AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml]

Iterate this transaction’s own data responses as they arrive, until Done/Error.

Unlike wait_complete(), which buffers everything and returns once the transaction finishes, this yields each response as soon as it is received - for a handler that streams results incrementally (e.g. ScanOnLine, see pyippdme.simulation.classes.scanning_class), so a caller can react to (or interrupt after) each point instead of waiting for the whole scan to finish. Raises the same errors wait_complete() would, once the stream ends.

async events() → AsyncIterator[NumericData | PropertyData | Items | StringValue | NameValue | Xml]

Iterate data responses arriving after wait_complete() (daemon events).

Abstract syntax tree for the I++ DME wire grammar.

The grammar is formally defined in section 5.2 using Extended Backus-Naur Form. Every node below can render itself back to wire text via to_wire(), so the AST is the single source of truth for both parsing (see pyippdme.protocol.parser) and encoding.

Four deliberate deviations from a literal transcription of the grammar are noted where they occur:

  • The XML payload referenced by method = basicName '(' (methodArgumentList | xml) ')' is left undefined by the standard (xml = @XMLDocumentString@@@). Xml stores the raw text verbatim between the outer parentheses.

  • The grammar’s data = numericalData | propertyData | method | propertyList production is ambiguous: a bare Name(number, ...) matches both method and a one-item propertyList, and there is no rule disambiguating a response body that mixes plain numbers with named groups (e.g. ChangeToolAction(Switch, X(0), Y(0), Z(-8)) seen in real implementations). pyippdme.protocol.parser resolves this by parsing any non-numeric, non-property-pair response body as a comma-separated list of NamedValue/Argument nodes (see Items below), which is a strict superset of both method and propertyList.

  • The standard never says how xml combines with data or with a property/named group’s own argument list, yet several real properties (e.g. Tool.Id(), AdvDataStruct()) return XML documents. This grammar adds xml as a top-level data alternative (a bare XML response, like StringValue/NameValue already cover the single-plain-value case) and, mirroring how Method already resolves the identical ambiguity for command arguments, a mutually-exclusive xml field on NamedValue for the “one named XML property” case.

  • A command argument’s own name(...) sub-group (the standard’s informal property shorthand within a methodArgumentList) is written as if it can only ever hold a flat list of numbers, but real commands need it to hold further named sub-groups and bare names too - e.g. ScanOnCurve’s Format(X(),Y(),Z(),IJK(),tag) (Table 85), confirmed against a real captured wire line in the NIST/I++ DME reference test suite’s ScanOnCurve.prg. pyippdme.protocol.parser resolves this by giving a command argument’s name(...) group the same fully recursive argument grammar as a response’s named group already has (they are otherwise identical productions), rather than a separate, artificially numbers-only one.

class pyippdme.protocol.ast.Tag(value: str)

A 5-digit command tag, 00001-99999 (5.4.1). 00000 is reserved.

MAX: ClassVar[int] = 99999

Largest tag number of() accepts; also what IppDmeClient() cycles back to 1 after when allocating one, so the two can’t drift apart.

class pyippdme.protocol.ast.EventTag(value: str)

An event tag E0001-E9999. E0000 denotes unsolicited events.

MAX: ClassVar[int] = 9999

Largest event tag number of() accepts; also what IppDmeClient() cycles back to 1 after when allocating one (0 itself is never allocated there - it is reserved for UNSOLICITED).

pyippdme.protocol.ast.TagLike = pyippdme.protocol.ast.Tag | pyippdme.protocol.ast.EventTag

Either kind of tag that can prefix a command or response line.

pyippdme.protocol.ast.parse_tag(text: str) → Tag | EventTag

Parse either a Tag or an EventTag from its wire text.

class pyippdme.protocol.ast.Number(text: str)

A numeric literal, at most 16 characters (5.3.1).

classmethod of(value: float | int) → Number

Format value as wire text, guaranteed to fit the 16-character limit.

Prefers Python’s shortest round-trip repr(), which is exact and usually well under the limit, but falls back to reduced-precision %g formatting for values (e.g. irrational trig results) whose exact repr would exceed it.

class pyippdme.protocol.ast.String(value: str)

A quoted string. Wire text may not itself contain a " character.

class pyippdme.protocol.ast.BasicName(value: str)

A bare identifier used as an unquoted enum/name argument, e.g. Switch.

class pyippdme.protocol.ast.Xml(raw: str)

Raw XML payload of a method, verbatim between its outer parentheses.

The standard does not define this production (see module docstring), so no attempt is made to parse or validate the XML content itself.

class pyippdme.protocol.ast.NamedValue(name: str, args: tuple[Number | String | NamedValue | EventTag | BasicName, ...] = (), xml: Xml | None = None)

A dotted name applied to a parenthesized argument list, or an XML payload.

Covers both the property production (name '(' numbers ')', used e.g. as a command argument like X(5)) and nested named groups that appear inside response data (e.g. ChangeToolAction(Switch, X(0))).

xml mirrors Method: a handful of properties are themselves XML documents (e.g. Tool.Id(), 6.10.3; Tool.AdvDataStruct(), 6.17.2) - the standard’s own grammar does not define how xml combines with the rest of the data/property productions, so (matching how Method already resolves the identical ambiguity for command arguments) it is a separate, mutually-exclusive field rather than a member of Argument, which the XML token’s own “consume to the closing paren” lexing does not allow to safely sit alongside sibling arguments anyway.

pyippdme.protocol.ast.Argument = pyippdme.protocol.ast.Number | pyippdme.protocol.ast.String | pyippdme.protocol.ast.NamedValue | pyippdme.protocol.ast.EventTag | pyippdme.protocol.ast.BasicName

Any value that may appear as a method/property argument.

class pyippdme.protocol.ast.Method(name: str, args: tuple[Number | String | NamedValue | EventTag | BasicName, ...] = (), xml: Xml | None = None)

A method call: a name applied to an argument list or an XML payload.

class pyippdme.protocol.ast.Command(tag: Tag | EventTag, method: Method)

A command line sent by the client: tag SP method CRLF.

class pyippdme.protocol.ast.AckResponse(tag: Tag | EventTag)

Acknowledgement response: tag SP '&'.

class pyippdme.protocol.ast.DoneResponse(tag: Tag | EventTag)

Transaction-complete response: tag SP '%'.

class pyippdme.protocol.ast.NumericData(values: tuple[Number, ...])

A comma-separated list of bare numbers (numericalData).

class pyippdme.protocol.ast.PropertyData(first: String, second: String)

Exactly two strings (propertyData), e.g. a property name/type pair.

class pyippdme.protocol.ast.NameValue(value: str)

A single bare (unquoted) name-typed value as a whole data response.

Section 5.3.5 defines name as “a special case of enum … in case of returned data, it refers to a string, but without quotation marks”, e.g. the Csy returned by GetCoordSystem(). Like StringValue, this has no direct alternative in the formal data production.

class pyippdme.protocol.ast.StringValue(value: String)

A single bare (unwrapped, “Kind U”) string as a whole data response.

Not a named production of the formal grammar: several commands (e.g. GetSupportedCommands(), EnumNameSpaces()) define a single unnamed string return value sent as “a separate message” per item, which the data production (numericalData | propertyData | method | propertyList) has no direct alternative for. This is the pragmatic reading used throughout the reference command classes in this project.

class pyippdme.protocol.ast.Items(values: tuple[NamedValue, ...])

A comma-separated list of named values, covering method/propertyList.

See the module docstring for why this generalization is needed.

pyippdme.protocol.ast.DataPayload = pyippdme.protocol.ast.NumericData | pyippdme.protocol.ast.PropertyData | pyippdme.protocol.ast.Items | pyippdme.protocol.ast.StringValue | pyippdme.protocol.ast.NameValue | pyippdme.protocol.ast.Xml

The payload of a data response. Xml covers commands whose sole returned value is itself an XML document (e.g. AdvDataStruct(), 6.17.2) - the standard’s grammar does not define this either (see the module docstring), so it is added as a bare top-level alternative, mirroring how StringValue/ NameValue already cover the single-plain-value case.

class pyippdme.protocol.ast.DataResponse(tag: Tag | EventTag, data: NumericData | PropertyData | Items | StringValue | NameValue | Xml)

Data response: tag SP '#' SP data.

The standard is internally inconsistent here. Its formal EBNF (5.2: dataResponse = (tag | eventTag) ' #' data) puts no space between # and the payload, but its own prose two pages later (5.4.2: “If the response line contains more content, the eighth character must again be a space”) requires exactly that space, and every real-world example in the standard follows the prose, not the EBNF. to_wire() always emits it; parser accepts either form on input.

class pyippdme.protocol.ast.ErrorResponse(tag: Tag | EventTag, severity: int, number: str, cause: str, text: str)

Error response: tag SP '!' SP 'Error(' F1 ',' F2 ',' F3 ',' Text ')'.

pyippdme.protocol.ast.Response = pyippdme.protocol.ast.AckResponse | pyippdme.protocol.ast.DoneResponse | pyippdme.protocol.ast.DataResponse | pyippdme.protocol.ast.ErrorResponse

Any response line the server may send.

Error classification and the pre-defined error table (5.6, Annex B).

class pyippdme.protocol.errors.ErrorSeverity(*values)

F1: default error severity classification (Table 4).

property requires_clear_all_errors: bool

Whether a client must send ClearAllErrors() before continuing.

exception pyippdme.protocol.errors.ServerError(severity: ErrorSeverity, number: str, cause: str, text: str)

A parsed Error(F1, F2, F3, Text) response (5.6.3).

number: str

4-digit error number identifying the error, e.g. "1008".

Type:

F2

cause: str

name of the method that reported the error.

Type:

F3

text: str

Additional human-readable information.

class pyippdme.protocol.errors.ErrorCode(*values)

4-digit error numbers pre-defined by I++ DME (Annex B).

A str subtype (ErrorCode.BAD_ARGUMENT == "0509" is True), so it can be passed anywhere ServerError’s number field or a wire-text comparison expects a plain string - the point of naming these is to replace scattered raw "0509"-style literals at every call site that raises a pre-defined error with a name that a typo in the digits can’t silently slip past (mypy/the IDE catch an unknown name; nothing catches a wrong but well-formed 4-digit string).

Numbers below 8000 are reserved by the specification; 8000-8999 and 9000-9999 are free for server- and client-defined proprietary errors respectively (5.6.3), so are intentionally not members here - a real error number outside this enum is not necessarily invalid, just not one of these pre-defined ones.

pyippdme.protocol.errors.DEFAULT_ERRORS: dict[ErrorCode, tuple[ErrorSeverity, str]] = {ErrorCode.BUFFER_FULL: (ErrorSeverity.INFO, 'Buffer full'), ErrorCode.ILLEGAL_TAG: (ErrorSeverity.ERROR, 'Illegal tag'), ErrorCode.NO_SPACE_AT_POSITION_6: (ErrorSeverity.ERROR, 'No space at pos. 6'), ErrorCode.RESERVED_0003: (ErrorSeverity.ERROR, 'Reserved'), ErrorCode.RESERVED_0004: (ErrorSeverity.ERROR, 'Reserved'), ErrorCode.RESERVED_0005: (ErrorSeverity.ERROR, 'Reserved'), ErrorCode.TRANSACTION_ABORTED: (ErrorSeverity.ERROR, 'Transaction aborted (Use ClearAllErrors To Continue)'), ErrorCode.ILLEGAL_CHARACTER: (ErrorSeverity.CRITICAL, 'Illegal character'), ErrorCode.PROTOCOL_ERROR: (ErrorSeverity.CRITICAL, 'Protocol error'), ErrorCode.EMERGENCY_STOP: (ErrorSeverity.CRITICAL, 'Emergency stop'), ErrorCode.UNSUPPORTED_COMMAND: (ErrorSeverity.CRITICAL, 'Unsupported command'), ErrorCode.INCORRECT_ARGUMENTS: (ErrorSeverity.CRITICAL, 'Incorrect arguments'), ErrorCode.CONTROLLER_COMMUNICATIONS_FAILURE: (ErrorSeverity.FATAL, 'Controller communications failure'), ErrorCode.ARGUMENT_OUT_OF_RANGE: (ErrorSeverity.WARNING, 'Argument out of range'), ErrorCode.ARGUMENT_NOT_RECOGNIZED: (ErrorSeverity.CRITICAL, 'Argument not recognized'), ErrorCode.ARGUMENT_NOT_SUPPORTED: (ErrorSeverity.CRITICAL, 'Argument not supported'), ErrorCode.ILLEGAL_COMMAND: (ErrorSeverity.CRITICAL, 'Illegal command'), ErrorCode.BAD_CONTEXT: (ErrorSeverity.CRITICAL, 'Bad context'), ErrorCode.BAD_ARGUMENT: (ErrorSeverity.CRITICAL, 'Bad argument'), ErrorCode.BAD_PROPERTY: (ErrorSeverity.CRITICAL, 'Bad property'), ErrorCode.ERROR_PROCESSING_METHOD: (ErrorSeverity.CRITICAL, 'Error processing method'), ErrorCode.NO_DAEMONS_ACTIVE: (ErrorSeverity.WARNING, 'No daemons are active'), ErrorCode.DAEMON_DOES_NOT_EXIST: (ErrorSeverity.ERROR, 'Daemon does not exist'), ErrorCode.USE_CLEAR_ALL_ERRORS: (ErrorSeverity.ERROR, 'Use ClearAllErrors to continue'), ErrorCode.DAEMON_ALREADY_EXISTS: (ErrorSeverity.ERROR, 'Daemon already exists'), ErrorCode.MACHINE_IN_ERROR_STATE: (ErrorSeverity.CRITICAL, 'Machine in error state'), ErrorCode.ILLEGAL_TOUCH: (ErrorSeverity.ERROR, 'Illegal touch'), ErrorCode.AXIS_DOES_NOT_EXIST: (ErrorSeverity.FATAL, 'Axis does not exist'), ErrorCode.NO_TOUCH: (ErrorSeverity.ERROR, 'No touch'), ErrorCode.ANGLES_NOT_SUPPORTED: (ErrorSeverity.FATAL, 'Number of angles not supported on current device'), ErrorCode.ERROR_DURING_HOME: (ErrorSeverity.CRITICAL, 'Error during home'), ErrorCode.SURFACE_NOT_FOUND: (ErrorSeverity.ERROR, 'Surface not found'), ErrorCode.THETA_OUT_OF_RANGE: (ErrorSeverity.CRITICAL, 'Theta out of range'), ErrorCode.TARGET_OUT_OF_MACHINE_VOLUME: (ErrorSeverity.CRITICAL, 'Target position out of machine volume'), ErrorCode.AIR_PRESSURE_OUT_OF_RANGE: (ErrorSeverity.CRITICAL, 'Air pressure out of range'), ErrorCode.VECTOR_HAS_NO_NORM: (ErrorSeverity.ERROR, 'Vector has no norm'), ErrorCode.UNABLE_TO_MOVE: (ErrorSeverity.ERROR, 'Unable to move'), ErrorCode.BAD_LOCK_COMBINATIONS: (ErrorSeverity.ERROR, 'Bad lock combinations'), ErrorCode.COORDINATE_SYSTEM_NOT_FOUND: (ErrorSeverity.CRITICAL, 'Coordinate system not found'), ErrorCode.ACTIVE_INTERNAL_CORRECTION: (ErrorSeverity.ERROR, 'Failed to set value due to active internal correction'), ErrorCode.FAILED_TO_RESEAT_HEAD: (ErrorSeverity.CRITICAL, 'Failed to re-seat head'), ErrorCode.PROBE_NOT_ARMED: (ErrorSeverity.CRITICAL, 'Probe not armed'), ErrorCode.TOOL_NOT_FOUND: (ErrorSeverity.CRITICAL, 'Tool not found'), ErrorCode.TOOL_NOT_DEFINED: (ErrorSeverity.CRITICAL, 'Tool not defined'), ErrorCode.COLLECTION_NOT_FOUND: (ErrorSeverity.CRITICAL, 'Collection not found'), ErrorCode.TOOL_NOT_ALIGNABLE: (ErrorSeverity.ERROR, 'Tool not alignable'), ErrorCode.TOOL_PROPERTY_NOT_APPLICABLE: (ErrorSeverity.WARNING, 'Tool property not applicable'), ErrorCode.TOOL_NOT_ALIGNABLE_TO_ORIENTATION: (ErrorSeverity.CRITICAL, 'Tool not alignable to given orientation'), ErrorCode.TOOL_NOT_CALIBRATED: (ErrorSeverity.CRITICAL, 'Tool not calibrated'), ErrorCode.HEAD_ERROR_EXCESSIVE_FORCE: (ErrorSeverity.ERROR, 'Head error excessive force'), ErrorCode.PROBE_TYPE_NOT_ALLOWED: (ErrorSeverity.CRITICAL, 'Type of probe does not allow this operation'), ErrorCode.RAW_DATA_NOT_AVAILABLE: (ErrorSeverity.CRITICAL, 'Raw data of Acquisition not available'), ErrorCode.NO_SHARED_MEMORY_AVAILABLE: (ErrorSeverity.CRITICAL, 'No shared memory space available'), ErrorCode.FILE_NOT_FOUND: (ErrorSeverity.CRITICAL, 'File not found'), ErrorCode.MACHINE_LIMIT_ENCOUNTERED: (ErrorSeverity.CRITICAL, 'Machine limit encountered [Move Out Of Limits]'), ErrorCode.AXIS_NOT_ACTIVE: (ErrorSeverity.CRITICAL, 'Axis not active'), ErrorCode.AXIS_POSITION_ERROR: (ErrorSeverity.CRITICAL, 'Axis position error'), ErrorCode.SCALE_READ_HEAD_FAILURE: (ErrorSeverity.FATAL, 'Scale read head failure'), ErrorCode.COLLISION: (ErrorSeverity.CRITICAL, 'Collision'), ErrorCode.ANGLE_OUT_OF_RANGE: (ErrorSeverity.ERROR, 'Specified angle out of range'), ErrorCode.PART_NOT_ALIGNED: (ErrorSeverity.ERROR, 'Part not aligned'), ErrorCode.WRONG_DATA_FORMAT: (ErrorSeverity.ERROR, 'Wrong data format'), ErrorCode.PORT_NOT_AVAILABLE: (ErrorSeverity.ERROR, 'Port not available')}

Pre-defined errors of I++ DME (Annex B), keyed by 4-digit number.

pyippdme.protocol.errors.describe(number: str) → tuple[ErrorSeverity, str] | None

Look up the default severity/text of a pre-defined error number, if known.

number need not itself be an ErrorCode - a plain wire-text string (e.g. parsed from a remote server’s response, which may well be a proprietary 8000-9999 code this enum intentionally excludes) is resolved the same way, returning None for anything not pre-defined.

A transparent I++ DME proxy (ippdme spy’s underlying implementation).

Spy binds a listening socket and, for each incoming client connection, opens a new outbound connection to the real server and relays bytes in both directions unchanged - it never decodes a line through pyippdme.protocol.parser/re-encodes it, deliberately, so nothing here can normalize or subtly alter what either side actually sent (a byte-for-byte relay is what a spy is for; round-tripping through the AST would only be able to approximate that). Line boundaries (\r\n, per 5.1) are still respected, since that is what lets each message be reported to on_message as a discrete event rather than an arbitrary chunk of bytes.

on_message/on_connect/on_disconnect are observe-only: they are told what was relayed, but cannot change, delay, or block it. To filter, alter, delay or multiply messages, pass an intercept function (Interceptor); without one, every line is forwarded unchanged. ippdme spy (pyippdme.cli.spy) is a thin console-logging consumer of this same class, not a separate implementation - embedding a spy in your own tooling (recording a session, feeding traffic to an analyzer, rewriting commands, …) uses exactly this API.

class pyippdme.spy.SpyDirection(*values)

Which way a relayed message travelled.

class pyippdme.spy.SpyOutcome(*values)

What a Spy did with a received line.

class pyippdme.spy.SpyMessage(connection_id: int, direction: SpyDirection, timestamp: datetime, line: bytes, forwarded: tuple[bytes, ...] | None = None)

One line received by Spy (including its trailing \r\n).

line is the line as it arrived. forwarded is what was sent on in its place: None if it was forwarded unchanged, otherwise the lines an intercept function returned (empty if the message was dropped).

pyippdme.spy.MessageHook

A hook is a plain, synchronous callable - matching this project’s existing convention for lightweight observation points (see PropertySetHandler). One that needs to do async work of its own (write to a file, push to a queue, …) should spawn its own asyncio.create_task(...) rather than this class supporting a parallel async-callable signature for the same purpose. A hook that raises is logged and otherwise ignored - a bug in observation code must not take down the relay itself.

alias of Callable[[SpyMessage], None]

pyippdme.spy.Interceptor

Decides what to forward in place of a received line. It is awaited before anything is sent on, so it may also delay a message. Return the same bytes to forward unchanged, other bytes to alter the message, None, empty bytes or an empty sequence to drop it, or several lines to replace it with more than one. Returned lines should end in \r\n (5.1). Lines of one direction are processed one at a time, in order. Dropping or altering a command can leave the client waiting for a response the server never sends; the spy does not invent one. An interceptor that raises is logged and the connection is closed.

alias of Callable[[SpyMessage], Awaitable[bytes | Sequence[bytes] | None]]

class pyippdme.spy.Spy(host: str, port: int, *, network: ~pyippdme.protocol.network.Network = <pyippdme.protocol.network.TcpNetwork object>, intercept: ~collections.abc.Callable[[~pyippdme.spy.SpyMessage], ~collections.abc.Awaitable[bytes | ~collections.abc.Sequence[bytes] | None]] | None = None, on_message: ~collections.abc.Callable[[~pyippdme.spy.SpyMessage], None] | None = None, on_connect: ~collections.abc.Callable[[int, str], None] | None = None, on_disconnect: ~collections.abc.Callable[[int, str], None] | None = None)

Relay every byte between a client and the real server at host:port.

See the module docstring for what “unchanged” and “observe-only” mean here. Method names/shapes deliberately match IppDmeServer’s own (start()/ serve_forever()/close()/port), so embedding a spy alongside other asyncio work looks the same as embedding a server:

spy = Spy("192.168.1.50", 1294, on_message=lambda m: print(m))
port = await spy.start("127.0.0.1", 0)
...
await spy.close()
async start(host: str = '127.0.0.1', port: int = 0) → int

Bind and start accepting connections without blocking; return the bound port.

port=0 lets the OS pick a free port, returned here so the caller can connect to it (embedding a spy in a test, say). Call close() when done.

property port: int | None

The port currently bound by start()/serve_forever(), or None.

The pluggable interface between a move command and the machine that carries it out.

Without a motion model a move (GoTo, Step, PtMeas, …) simply sets the new position, instantly and without any limits - what the minimal VirtualCMM does. A MotionModel makes a move take time, keep within the machine volume, stop at a collision, or wait for Home(): the move handlers await MotionModel.travel() before they update the position, and a ServerError raised by it is the command’s error response. Like SampleSurface this module holds only the interface; the concrete models live in the packages that depend on it (see pyippdme.twin).

class pyippdme.server.motion.MotionRequest(cause: str, start: tuple[float, float, float], end: tuple[float, float, float], rotary_start: float, rotary_end: float, homed: bool, tool_name: str, cancel: Event)

One straight move of the tool centre point (and optionally the rotary table).

cause: str

The command that moves, e.g. GoTo or PtMeas.

tool_name: str

Name of the active tool, a key of the tool catalog.

cancel: Event

Set when the move must stop as soon as possible (AbortE()).

class pyippdme.server.motion.ProbeRequest(cause: str, nominal: tuple[float, float, float], direction: tuple[float, float, float], approach: float, search: float, retract: float, speed: float, accel: float, tool_name: str, cancel: Event)

The probing cycle of PtMeas (6.12.1) from the approach position.

The machine stands at nominal + direction * approach; direction points from the surface towards the probe. approach is Part.Approach + Tool.Approach + AvrRadius (6.12.1): for a tool with a ball the tool centre point starts one radius further out. The search goes on until search beyond the nominal point, measured at the tip (so a ball centre travels approach - radius + search), and the machine retracts by retract (negative: back to the approach position) after the trigger.

speed: float

Speed and acceleration of the search (PtMeasPar).

class pyippdme.server.motion.ProbeResult(contact: tuple[float, float, float], rest: tuple[float, float, float])

What the cycle found: the measured surface point and where the machine rests.

contact: tuple[float, float, float]

The measured point on the surface (compensated for the tip radius).

rest: tuple[float, float, float]

Tool centre point after the retract.

exception pyippdme.server.motion.MotionError(severity: ErrorSeverity, number: str, cause: str, text: str, stopped_at: Vec3)

A move that ended early: the machine stands at stopped_at, not at the target.

class pyippdme.server.motion.ToolHandler(*args, **kwargs)

The physical side of changing and qualifying tools.

Without one, ChangeTool and ReQualify take no time and always succeed. A handler can animate the trip to the tool rack, refuse while the machine is not ready, or find the reference sphere for ReQualify; raise a ServerError to fail the command.

alignment_volume(tool_name: str) → tuple[tuple[float, float, float], float] | None

Return the sphere the tool occupies while aligned (Tool.AlignmentVolume, Fig. 52/53).

(centre, radius): the vector from the tool’s reference point to the sphere centre, in machine coordinates, and the radius. None if the tool has no such volume.

collision_volume(tool_name: str) → list[Obb] | None

Oriented bounding boxes covering the tool (Tool.CollisionVolume, Figures 49-51).

Centres relative to the tool’s reference point and axes, in machine coordinates. None if the tool has no such volume.

class pyippdme.server.motion.CalibrationAware(*args, **kwargs)

Optional part of a ToolHandler: which tools are calibrated.

False makes Tool.Alignment and Tool.AvrOffsets fail with 2000 “Tool not calibrated” (Tables 114 and 116). Without it every tool counts as calibrated.

class pyippdme.server.motion.OffsetProvider(*args, **kwargs)

Optional part of a ToolHandler: the average tool offsets (Table 116).

Returns them in machine coordinates, or None to answer with zeros.

class pyippdme.server.motion.RadiusProvider(*args, **kwargs)

Optional part of a ToolHandler: the average tip radius (AvrRadius, Table 106).

The approach position of PtMeas lies Part.Approach + Tool.Approach + AvrRadius from the nominal point (6.12.1), so a tool with a ball reports its radius here. Without it the radius is zero, as for optical tools.

class pyippdme.server.motion.AlignmentSolver(*args, **kwargs)

Optional part of a ToolHandler: the orientation a tool really reaches.

AlignTool and the Tool.A/Tool.B/Tool.Alignment arguments of GoTo ask it. It returns the primary (and secondary) direction the head ends up in, which is not exactly the requested one for a head that indexes in steps, and raises 2505 for an angle the head cannot reach. Without it every orientation is reached exactly.

class pyippdme.server.motion.TemperatureProvider(*args, **kwargs)

Optional part of a MotionModel: the temperatures the machine really has.

The temperature sensors of 6.5.2 (ReadTemperatureSensor, ReadAllTemperatures) and UpdateScaleTemperatures read them. Without it the sensors answer from what the client set.

class pyippdme.server.motion.MotionModel(*args, **kwargs)

Carries out a move; returns the position the tool centre point ends at.

async probe(request: ProbeRequest) → ProbeResult

Search for the surface from the approach position; raise 1006 if none is found.

csy_context() → CsyContext | None

Return the coordinate system chain as this machine has it, or None for the default.

A model that knows more than the commands set (the angle of its rotary table for RotaryTableVarCsy) returns the complete context; the position a client reads is kept consistent through it when the client changes coordinate system.

async home(cancel: Event) → tuple[float, float, float] | None

Drive to the reference position for Home(); raise a ServerError if it cannot.

Returns where the machine stands afterwards in the coordinates a client sees (the active coordinate system), or None for the machine’s own home position.

The pluggable interface between PtMeas and a real (or synthetic) part.

Without a surface, PtMeas (6.12.1) simply reports whatever position the client commanded - there is nothing for the probe to actually touch, so approach/search/retract distances and the IJK probing direction are accepted but have no effect (see pyippdme.simulation.classes.cartcmm_class’s module docstring). SampleSurface is the seam that changes that: a IppDmeServer/VirtualCMM configured with one gets a real, if synthetic, part for PtMeas to measure against - a measured point can genuinely diverge from the commanded one, and “no surface found” becomes a real, reachable error (1006) instead of something that can never happen. This module holds only the interface itself - the concrete geometry (planes, spheres, cylinders) lives in pyippdme.simulation.surface, which depends on this module, not the other way around; a real integrator with an actual CAD/mesh representation of the part implements this same one-method Protocol directly instead.

class pyippdme.server.surface.SampleSurface(*args, **kwargs)

A synthetic surface a probing ray can intersect (structural - no inheritance needed).

direction need not be normalized. Returns the nearest intersection point with t >= 0 along direction from origin, or None if the ray never meets the surface (including when the surface is entirely behind origin). Implementations don’t need to know or care how far the caller intends to search - that bound is applied by the caller (pyippdme.simulation.classes.cartcmm_class), against Tool/Part’s Approach/Search properties.

class pyippdme.server.surface.RawSensor(*args, **kwargs)

A simulated optical/laser sensor that answers DataAcquire (6.15.1).

Without one, DataAcquire synthesizes points from the requested positions alone. With one, the sensor decides what it sees: positions and directions are the control points the client sent (one per n; a single TCP position for n == 0), acquisition_type is SingleShot, MultiShot or Sweep. Return None to fall back to the built-in synthesis.

Run an I++ DME client on a background thread, for front ends that own the main thread.

The counterpart of pyippdme.server.host.ServerHost: a GUI keeps its thread, the asyncio loop runs here. Every command runs as its own task, so a long GoTo does not block AbortE or a status query sent meanwhile. Callbacks run on the loop thread; a Qt front end hands them over with a signal.

pyippdme.client.host.EventHandler

Called with the command text and each step of its transaction.

alias of Callable[[str, ParseFailed | Acked | Received | Completed | Failed | ConnectionLost], None]

class pyippdme.client.host.ClientHost

One connection to a server, driven from any thread.

connect(host: str, port: int) → Future[None]

Connect over TCP; the future fails with the connection error.

connect_embedded(server: IppDmeServer[Any] | None = None) → Future[None]

Start a server in this process (default: the CLI’s --virtual machine) and connect.

run(text: str, on_event: Callable[[str, ParseFailed | Acked | Received | Completed | Failed | ConnectionLost], None]) → Future[None]

Send one command line; on_event gets each step. Commands may overlap.

run_lines(lines: list[str], on_event: Callable[[int, str, ParseFailed | Acked | Received | Completed | Failed | ConnectionLost], None]) → Future[bool]

Send the lines one after the other; on_event also gets the index of the line.

Stops at the first error and returns whether all lines succeeded. Different calls may overlap, so a long move does not block AbortE.

sensor_info() → Future[SensorInfo]

Return the active tool and how its raw data is delivered.

acquire(**options: Any) → Future[ScanData]

Run DataAcquire with the active tool and fetch the points.

run_sequence(lines: list[str], on_event: Callable[[str, ParseFailed | Acked | Received | Completed | Failed | ConnectionLost], None]) → Future[bool]

Send the lines one after the other; stops at the first error. True if all succeeded.

Ready-made command lines for the usual measuring tasks, for any front end.

Each function returns the text of one command (or the few commands a task needs, in order) that parse_method() accepts and a server answers:

goto_line(x=10, y=20)                 # 'GoTo(X(10),Y(20))'
pt_meas_line((10, 20, 0), (0, 0, 1))  # 'PtMeas(X(10),Y(20),Z(0),IJK(0,0,1))'
scan_line_lines((0, 0, 0), (50, 0, 0), (0, 0, 1), 2.0)  # ['OnScanReport(X,Y,Z)', ...]
pyippdme.client.recipes.AXIS_DIRECTIONS: dict[str, tuple[float, float, float]] = {'+X': (1.0, 0.0, 0.0), '+Y': (0.0, 1.0, 0.0), '+Z': (0.0, 0.0, 1.0), '-X': (-1.0, 0.0, 0.0), '-Y': (0.0, -1.0, 0.0), '-Z': (0.0, 0.0, -1.0)}

Probing directions along the machine axes, for buttons.

pyippdme.client.recipes.SPEED_PARAMETERS = {'GoToPar': 'Move (GoTo)', 'PtMeasPar': 'Point measurement', 'ScanPar': 'Scan'}

The parameter blocks of the active tool and what they hold (6.10.4, Table 77, 6.13.2).

pyippdme.client.recipes.goto_line(x: float | None = None, y: float | None = None, z: float | None = None, *, r: float | None = None, sync: bool | None = None, relative: bool = False) → str

GoTo (absolute) or Step (relative); axes left as None stay where they are.

pyippdme.client.recipes.named_csy_line(command: str, name: str) → str

SaveActiveCoordSystem, LoadCoordSystem or DeleteCoordSystem for name.

pyippdme.client.recipes.pt_meas_line(position: tuple[float, float, float], direction: tuple[float, float, float] | None = None, *, r: float | None = None) → str

PtMeas at a nominal position, probing along direction (6.12.1).

pyippdme.client.recipes.scan_circle_lines(center: tuple[float, float, float], start: tuple[float, float, float], normal: tuple[float, float, float], delta: float, surface_angle: float, step_width: float, *, pitch: float = 0.0, rotary: bool | None = None) → list[str]

Scan a circular arc, or a helix when pitch is not zero (6.13.2.1).

pyippdme.client.recipes.scan_line_lines(start: tuple[float, float, float], end: tuple[float, float, float], direction: tuple[float, float, float], step_width: float, *, rotary: bool | None = None) → list[str]

Report X,Y,Z per scan point, then scan a straight line (6.13.2.1).

pyippdme.client.recipes.set_coord_system_line(csy: str) → str

Choose the coordinate system the client works in (6.5.2).

pyippdme.client.recipes.set_csy_transformation_line(csy: str, offset: tuple[float, float, float], theta: float, psi: float, phi: float) → str

Place csy relative to its parent: offset and the Euler angles of 6.5.1.

pyippdme.client.recipes.speed_line(block: str, parameter: str, value: float) → str

Set one parameter of a block, e.g. speed_line("PtMeasPar", "Retract", -1).

pyippdme.client.recipes.speed_lines(block: str, speed: float | None, accel: float | None) → list[str]

Set the speed and acceleration of a parameter block (see SPEED_PARAMETERS).

pyippdme.client.recipes.status_lines() → list[str]

List what a front end polls for its status bar: the position and the error state.

Build command lines from a form: what a front end needs to offer every command, without a GUI.

A command’s parameters come from the catalog of the bundled server classes (BUILTIN_COMMANDS) or from any catalog you build with build_command_catalog(). command_fields() describes one command as an ordered list of FormField, and build_command_line() turns the values a user typed into the text parse_method() accepts:

fields = command_fields("GoTo")                      # one enum field: "Positions"
build_command_line("GoTo", {"Positions": "X(10),Y(20)"})   # 'GoTo(X(10),Y(20))'
build_command_line("ScanOnLine", {"Sx": "0", ...})   # positional commands: bare values
pyippdme.client.commandform.COMMAND_GROUPS: dict[str, tuple[str, ...]] = {'Coordinate systems': ('SetCoordSystem', 'GetCoordSystem', 'SetCsyTransformation', 'GetCsyTransformation', 'SaveNamedCsyTransformation', 'GetNamedCsyTransformation', 'SaveActiveCoordSystem', 'LoadCoordSystem', 'DeleteCoordSystem', 'EnumCoordSystems', 'EnableRotaryTableVarCsy', 'AlignPart'), 'Features (deprecated)': ('ROI', 'FeatureExtract'), 'Form tester': ('CenterPart', 'TiltPart', 'TiltCenterPart'), 'Machine': ('GetDMEVersion', 'GetSupportedCommands', 'GetSupportedArguments', 'GetMachineClass', 'Home', 'IsHomed', 'EnableUser', 'DisableUser', 'IsUserEnabled', 'EnumerateMoverAxes'), 'Measure a point': ('OnPtMeasReport', 'PtMeas', 'PtMeasPar', 'PtMeasSelfCenter', 'PtMeasSelfCenterLocked'), 'Move': ('GoTo', 'Step', 'GoToOnCircle', 'GoToOnSpiral', 'Get', 'OnMoveReport', 'OnMoveReportE', 'LockAxis', 'LockPosition'), 'Optical and raw data': ('DataAcquire', 'DeleteAcquistion', 'DeleteAcquisition', 'DeleteAllAcquisitions', 'AdvDataStruct', 'RawDataBinSetup', 'GetRawDataBin', 'GetRawDataShaMem', 'ReleaseShaMem', 'GetRawDataFile', 'DelRawDataFile'), 'Properties': ('GetProp', 'GetPropE', 'SetProp', 'EnumProp', 'EnumAllProp'), 'Scan': ('OnScanReport', 'ScanPar', 'ScanOnLine', 'ScanOnCircle', 'ScanOnHelix', 'ScanOnCurve', 'ScanOnLineHint', 'ScanOnCircleHint', 'ScanOnCurveHint', 'ScanOnCurveDensity', 'ScanUnknownHint', 'ScanUnknownDensity', 'ScanInPlaneEndIsSphere', 'ScanInPlaneEndIsPlane', 'ScanInPlaneEndIsCyl', 'ScanInCylEndIsSphere', 'ScanInCylEndIsPlane'), 'Session and errors': ('StartSession', 'EndSession', 'AbortE', 'ClearAllErrors', 'GetErrStatusE', 'GetXtdErrStatus', 'GetErrorInfo', 'StopDaemon', 'StopAllDaemons', 'EnumNameSpaces'), 'Temperature': ('GetTemperatureSensors', 'ReadTemperatureSensor', 'ReadAllTemperatures', 'UpdateScaleTemperatures', 'SetScaleTemperatures', 'GetScaleTemperatures', 'SetTemperatureCompensationOrigin'), 'Tool': ('Tool', 'GoToPar', 'OptPar', 'IsAlignable', 'AlignTool', 'AvrRadius', 'CalcToolAlignment', 'CalcToolAngles', 'UseSmallestAngletoAlignTool', 'UseSmallestAngleToAlignTool', 'ReQualify', 'EnableOptimize', 'DisableOptimize', 'IsOptimizeEnabled'), 'Tool changer': ('EnumTools', 'ChangeTool', 'FindTool', 'FoundTool', 'SetTool', 'GetChangeToolAction', 'EnumToolCollection', 'EnumAllToolCollections', 'OpenToolCollection')}

The commands by the class of the object model that defines them (Figure 1, chapter 6).

class pyippdme.client.commandform.FormField(name: str, datatype: DataType, mandatory: bool, positional: bool)

One input of a command form.

positional: bool

Written as a bare value in call order, not as Name(value).

property hint: str

A short description for a tooltip or placeholder.

pyippdme.client.commandform.build_command_line(name: str, values: ~collections.abc.Mapping[str, str], fields: list[~pyippdme.client.commandform.FormField] | None = None, catalog: ~collections.abc.Mapping[str, ~pyippdme.server.catalog.CommandInfo] = mappingproxy({<CommandName.ABORT_E: 'AbortE'>: CommandInfo(name=<CommandName.ABORT_E: 'AbortE'>, arguments=()), <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>: CommandInfo(name=<CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>, arguments=()), <CommandName.ALIGN_PART: 'AlignPart'>: CommandInfo(name=<CommandName.ALIGN_PART: 'AlignPart'>, arguments=(Parameter(name='px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mx1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='my1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='px2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='py2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mx2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='my2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.ALIGN_TOOL: 'AlignTool'>: CommandInfo(name=<CommandName.ALIGN_TOOL: 'AlignTool'>, arguments=(Parameter(name='i1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='j2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='k2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.AVR_RADIUS: 'AvrRadius'>: CommandInfo(name=<CommandName.AVR_RADIUS: 'AvrRadius'>, arguments=()), <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>: CommandInfo(name=<CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>: CommandInfo(name=<CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>, arguments=(Parameter(name='Alignment', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.CENTER_PART: 'CenterPart'>: CommandInfo(name=<CommandName.CENTER_PART: 'CenterPart'>, arguments=(Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.CHANGE_TOOL: 'ChangeTool'>: CommandInfo(name=<CommandName.CHANGE_TOOL: 'ChangeTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>: CommandInfo(name=<CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>, arguments=()), <CommandName.DATA_ACQUIRE: 'DataAcquire'>: CommandInfo(name=<CommandName.DATA_ACQUIRE: 'DataAcquire'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='Type', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='AcquiseSettingsName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True))), <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>: CommandInfo(name=<CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), 'DeleteAcquisition': CommandInfo(name='DeleteAcquisition', arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>: CommandInfo(name=<CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>: CommandInfo(name=<CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>, arguments=()), <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>: CommandInfo(name=<CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>: CommandInfo(name=<CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>, arguments=()), <CommandName.DISABLE_USER: 'DisableUser'>: CommandInfo(name=<CommandName.DISABLE_USER: 'DisableUser'>, arguments=()), <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>: CommandInfo(name=<CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>, arguments=()), <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>: CommandInfo(name=<CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>, arguments=(Parameter(name='Bool', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True),)), <CommandName.ENABLE_USER: 'EnableUser'>: CommandInfo(name=<CommandName.ENABLE_USER: 'EnableUser'>, arguments=()), <CommandName.END_SESSION: 'EndSession'>: CommandInfo(name=<CommandName.END_SESSION: 'EndSession'>, arguments=()), <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>: CommandInfo(name=<CommandName.ENUM_ALL_PROP: 'EnumAllProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False),)), <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>: CommandInfo(name=<CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>: CommandInfo(name=<CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>, arguments=()), <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>: CommandInfo(name=<CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>, arguments=()), <CommandName.ENUM_PROP: 'EnumProp'>: CommandInfo(name=<CommandName.ENUM_PROP: 'EnumProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False),)), <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>: CommandInfo(name=<CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.ENUM_TOOLS: 'EnumTools'>: CommandInfo(name=<CommandName.ENUM_TOOLS: 'EnumTools'>, arguments=()), <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>: CommandInfo(name=<CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>, arguments=()), <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>: CommandInfo(name=<CommandName.FEATURE_EXTRACT: 'FeatureExtract'>, arguments=None), <CommandName.FIND_TOOL: 'FindTool'>: CommandInfo(name=<CommandName.FIND_TOOL: 'FindTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.FOUND_TOOL: 'FoundTool'>: CommandInfo(name=<CommandName.FOUND_TOOL: 'FoundTool'>, arguments=()), <CommandName.GET: 'Get'>: CommandInfo(name=<CommandName.GET: 'Get'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>: CommandInfo(name=<CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>: CommandInfo(name=<CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>, arguments=()), <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>: CommandInfo(name=<CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True),)), <CommandName.GET_DME_VERSION: 'GetDMEVersion'>: CommandInfo(name=<CommandName.GET_DME_VERSION: 'GetDMEVersion'>, arguments=()), <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>: CommandInfo(name=<CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>, arguments=()), <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>: CommandInfo(name=<CommandName.GET_ERROR_INFO: 'GetErrorInfo'>, arguments=(Parameter(name='ErrorNumber', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True),)), <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>: CommandInfo(name=<CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>, arguments=()), <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>: CommandInfo(name=<CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_PROP: 'GetProp'>: CommandInfo(name=<CommandName.GET_PROP: 'GetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_PROP_E: 'GetPropE'>: CommandInfo(name=<CommandName.GET_PROP_E: 'GetPropE'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>: CommandInfo(name=<CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>: CommandInfo(name=<CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>: CommandInfo(name=<CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>: CommandInfo(name=<CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>: CommandInfo(name=<CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>, arguments=(Parameter(name='CommandName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>: CommandInfo(name=<CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>, arguments=()), <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>: CommandInfo(name=<CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>, arguments=()), <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>: CommandInfo(name=<CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>, arguments=()), <CommandName.GO_TO: 'GoTo'>: CommandInfo(name=<CommandName.GO_TO: 'GoTo'>, arguments=(Parameter(name='Positions', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>: CommandInfo(name=<CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>: CommandInfo(name=<CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_PAR: 'GoToPar'>: CommandInfo(name=<CommandName.GO_TO_PAR: 'GoToPar'>, arguments=()), <CommandName.HOME: 'Home'>: CommandInfo(name=<CommandName.HOME: 'Home'>, arguments=()), <CommandName.IS_ALIGNABLE: 'IsAlignable'>: CommandInfo(name=<CommandName.IS_ALIGNABLE: 'IsAlignable'>, arguments=()), <CommandName.IS_HOMED: 'IsHomed'>: CommandInfo(name=<CommandName.IS_HOMED: 'IsHomed'>, arguments=()), <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>: CommandInfo(name=<CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>, arguments=()), <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>: CommandInfo(name=<CommandName.IS_USER_ENABLED: 'IsUserEnabled'>, arguments=()), <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>: CommandInfo(name=<CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.LOCK_AXIS: 'LockAxis'>: CommandInfo(name=<CommandName.LOCK_AXIS: 'LockAxis'>, arguments=(Parameter(name='Axis', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.LOCK_POSITION: 'LockPosition'>: CommandInfo(name=<CommandName.LOCK_POSITION: 'LockPosition'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>: CommandInfo(name=<CommandName.ON_MOVE_REPORT: 'OnMoveReport'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>: CommandInfo(name=<CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>: CommandInfo(name=<CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.ON_SCAN_REPORT: 'OnScanReport'>: CommandInfo(name=<CommandName.ON_SCAN_REPORT: 'OnScanReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>: CommandInfo(name=<CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.OPT_PAR: 'OptPar'>: CommandInfo(name=<CommandName.OPT_PAR: 'OptPar'>, arguments=()), <CommandName.PT_MEAS: 'PtMeas'>: CommandInfo(name=<CommandName.PT_MEAS: 'PtMeas'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.PT_MEAS_PAR: 'PtMeasPar'>: CommandInfo(name=<CommandName.PT_MEAS_PAR: 'PtMeasPar'>, arguments=()), <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>: CommandInfo(name=<CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>: CommandInfo(name=<CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.ROI: 'ROI'>: CommandInfo(name=<CommandName.ROI: 'ROI'>, arguments=None), <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>: CommandInfo(name=<CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>, arguments=(Parameter(name='RawDataFormat', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='Port', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), Parameter(name='LiveMode', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True))), <CommandName.RE_QUALIFY: 'ReQualify'>: CommandInfo(name=<CommandName.RE_QUALIFY: 'ReQualify'>, arguments=()), <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>: CommandInfo(name=<CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>, arguments=()), <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>: CommandInfo(name=<CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>: CommandInfo(name=<CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>: CommandInfo(name=<CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>: CommandInfo(name=<CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>: CommandInfo(name=<CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>: CommandInfo(name=<CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>: CommandInfo(name=<CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='d', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>: CommandInfo(name=<CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>: CommandInfo(name=<CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>: CommandInfo(name=<CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>: CommandInfo(name=<CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>, arguments=(Parameter(name='Displacement', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>: CommandInfo(name=<CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>, arguments=(Parameter(name=<ParameterName.CLOSED: 'Closed'>, datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=False), Parameter(name=<ParameterName.FORMAT: 'Format'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False), Parameter(name=<ParameterName.DATA: 'Data'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>: CommandInfo(name=<CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.AT_NOMINALS: 'AtNominals'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False))), <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>: CommandInfo(name=<CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>, arguments=(Parameter(name='Deviation', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>: CommandInfo(name=<CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pitch', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE: 'ScanOnLine'>: CommandInfo(name=<CommandName.SCAN_ON_LINE: 'ScanOnLine'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>: CommandInfo(name=<CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>, arguments=(Parameter(name='Angle', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_PAR: 'ScanPar'>: CommandInfo(name=<CommandName.SCAN_PAR: 'ScanPar'>, arguments=()), <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>: CommandInfo(name=<CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>: CommandInfo(name=<CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>, arguments=(Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True),)), <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>: CommandInfo(name=<CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True),)), <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>: CommandInfo(name=<CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SET_PROP: 'SetProp'>: CommandInfo(name=<CommandName.SET_PROP: 'SetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>: CommandInfo(name=<CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>, arguments=(Parameter(name='Temperatures', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False),)), <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>: CommandInfo(name=<CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>, arguments=(Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SET_TOOL: 'SetTool'>: CommandInfo(name=<CommandName.SET_TOOL: 'SetTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True),)), <CommandName.START_SESSION: 'StartSession'>: CommandInfo(name=<CommandName.START_SESSION: 'StartSession'>, arguments=()), <CommandName.STEP: 'Step'>: CommandInfo(name=<CommandName.STEP: 'Step'>, arguments=(Parameter(name='Distances', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>: CommandInfo(name=<CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>, arguments=()), <CommandName.STOP_DAEMON: 'StopDaemon'>: CommandInfo(name=<CommandName.STOP_DAEMON: 'StopDaemon'>, arguments=(Parameter(name='EventTag', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True),)), <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>: CommandInfo(name=<CommandName.TILT_CENTER_PART: 'TiltCenterPart'>, arguments=(Parameter(name='Px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TILT_PART: 'TiltPart'>: CommandInfo(name=<CommandName.TILT_PART: 'TiltPart'>, arguments=(Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TOOL: 'Tool'>: CommandInfo(name=<CommandName.TOOL: 'Tool'>, arguments=()), <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>: CommandInfo(name=<CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>, arguments=()), 'UseSmallestAngleToAlignTool': CommandInfo(name='UseSmallestAngleToAlignTool', arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True),)), <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>: CommandInfo(name=<CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>, arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True),))})) → str

Turn typed values into a command line; empty values are left out.

Positional commands write their values in order and stop at the first empty optional one (a gap in the middle is an error, as the protocol has no way to skip an argument). Raises ValueError when a mandatory value is missing.

pyippdme.client.commandform.command_fields(name: str, catalog: Mapping[str, ~pyippdme.server.catalog.CommandInfo]=mappingproxy({<CommandName.ABORT_E: 'AbortE'>: CommandInfo(name=<CommandName.ABORT_E: 'AbortE'>, arguments=()), <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>: CommandInfo(name = <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>, arguments=()), <CommandName.ALIGN_PART: 'AlignPart'>: CommandInfo(name = <CommandName.ALIGN_PART: 'AlignPart'>, arguments=(Parameter(name='px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mx1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='my1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='px2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='py2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mx2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='my2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.ALIGN_TOOL: 'AlignTool'>: CommandInfo(name = <CommandName.ALIGN_TOOL: 'AlignTool'>, arguments=(Parameter(name='i1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='j2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='k2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.AVR_RADIUS: 'AvrRadius'>: CommandInfo(name = <CommandName.AVR_RADIUS: 'AvrRadius'>, arguments=()), <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>: CommandInfo(name = <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>: CommandInfo(name = <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>, arguments=(Parameter(name='Alignment', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.CENTER_PART: 'CenterPart'>: CommandInfo(name = <CommandName.CENTER_PART: 'CenterPart'>, arguments=(Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.CHANGE_TOOL: 'ChangeTool'>: CommandInfo(name = <CommandName.CHANGE_TOOL: 'ChangeTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>: CommandInfo(name = <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>, arguments=()), <CommandName.DATA_ACQUIRE: 'DataAcquire'>: CommandInfo(name = <CommandName.DATA_ACQUIRE: 'DataAcquire'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='Type', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='AcquiseSettingsName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True))), <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>: CommandInfo(name = <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), 'DeleteAcquisition': CommandInfo(name = 'DeleteAcquisition', arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>: CommandInfo(name = <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>: CommandInfo(name = <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>, arguments=()), <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>: CommandInfo(name = <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>: CommandInfo(name = <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>, arguments=()), <CommandName.DISABLE_USER: 'DisableUser'>: CommandInfo(name = <CommandName.DISABLE_USER: 'DisableUser'>, arguments=()), <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>: CommandInfo(name = <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>, arguments=()), <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>: CommandInfo(name = <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>, arguments=(Parameter(name='Bool', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), )), <CommandName.ENABLE_USER: 'EnableUser'>: CommandInfo(name = <CommandName.ENABLE_USER: 'EnableUser'>, arguments=()), <CommandName.END_SESSION: 'EndSession'>: CommandInfo(name = <CommandName.END_SESSION: 'EndSession'>, arguments=()), <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>: CommandInfo(name = <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False), )), <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>: CommandInfo(name = <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>: CommandInfo(name = <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>, arguments=()), <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>: CommandInfo(name = <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>, arguments=()), <CommandName.ENUM_PROP: 'EnumProp'>: CommandInfo(name = <CommandName.ENUM_PROP: 'EnumProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False), )), <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>: CommandInfo(name = <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.ENUM_TOOLS: 'EnumTools'>: CommandInfo(name = <CommandName.ENUM_TOOLS: 'EnumTools'>, arguments=()), <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>: CommandInfo(name = <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>, arguments=()), <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>: CommandInfo(name = <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>, arguments=None), <CommandName.FIND_TOOL: 'FindTool'>: CommandInfo(name = <CommandName.FIND_TOOL: 'FindTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.FOUND_TOOL: 'FoundTool'>: CommandInfo(name = <CommandName.FOUND_TOOL: 'FoundTool'>, arguments=()), <CommandName.GET: 'Get'>: CommandInfo(name = <CommandName.GET: 'Get'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>: CommandInfo(name = <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>: CommandInfo(name = <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>, arguments=()), <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>: CommandInfo(name = <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.GET_DME_VERSION: 'GetDMEVersion'>: CommandInfo(name = <CommandName.GET_DME_VERSION: 'GetDMEVersion'>, arguments=()), <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>: CommandInfo(name = <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>, arguments=()), <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>: CommandInfo(name = <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>, arguments=(Parameter(name='ErrorNumber', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), )), <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>: CommandInfo(name = <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>, arguments=()), <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>: CommandInfo(name = <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_PROP: 'GetProp'>: CommandInfo(name = <CommandName.GET_PROP: 'GetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_PROP_E: 'GetPropE'>: CommandInfo(name = <CommandName.GET_PROP_E: 'GetPropE'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>: CommandInfo(name = <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>: CommandInfo(name = <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>: CommandInfo(name = <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>: CommandInfo(name = <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>: CommandInfo(name = <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>, arguments=(Parameter(name='CommandName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>: CommandInfo(name = <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>, arguments=()), <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>: CommandInfo(name = <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>, arguments=()), <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>: CommandInfo(name = <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>, arguments=()), <CommandName.GO_TO: 'GoTo'>: CommandInfo(name = <CommandName.GO_TO: 'GoTo'>, arguments=(Parameter(name='Positions', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>: CommandInfo(name = <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>: CommandInfo(name = <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_PAR: 'GoToPar'>: CommandInfo(name = <CommandName.GO_TO_PAR: 'GoToPar'>, arguments=()), <CommandName.HOME: 'Home'>: CommandInfo(name = <CommandName.HOME: 'Home'>, arguments=()), <CommandName.IS_ALIGNABLE: 'IsAlignable'>: CommandInfo(name = <CommandName.IS_ALIGNABLE: 'IsAlignable'>, arguments=()), <CommandName.IS_HOMED: 'IsHomed'>: CommandInfo(name = <CommandName.IS_HOMED: 'IsHomed'>, arguments=()), <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>: CommandInfo(name = <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>, arguments=()), <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>: CommandInfo(name = <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>, arguments=()), <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>: CommandInfo(name = <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.LOCK_AXIS: 'LockAxis'>: CommandInfo(name = <CommandName.LOCK_AXIS: 'LockAxis'>, arguments=(Parameter(name='Axis', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.LOCK_POSITION: 'LockPosition'>: CommandInfo(name = <CommandName.LOCK_POSITION: 'LockPosition'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>: CommandInfo(name = <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>: CommandInfo(name = <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>: CommandInfo(name = <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ON_SCAN_REPORT: 'OnScanReport'>: CommandInfo(name = <CommandName.ON_SCAN_REPORT: 'OnScanReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>: CommandInfo(name = <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.OPT_PAR: 'OptPar'>: CommandInfo(name = <CommandName.OPT_PAR: 'OptPar'>, arguments=()), <CommandName.PT_MEAS: 'PtMeas'>: CommandInfo(name = <CommandName.PT_MEAS: 'PtMeas'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.PT_MEAS_PAR: 'PtMeasPar'>: CommandInfo(name = <CommandName.PT_MEAS_PAR: 'PtMeasPar'>, arguments=()), <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>: CommandInfo(name = <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>: CommandInfo(name = <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ROI: 'ROI'>: CommandInfo(name = <CommandName.ROI: 'ROI'>, arguments=None), <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>: CommandInfo(name = <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>, arguments=(Parameter(name='RawDataFormat', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='Port', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), Parameter(name='LiveMode', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True))), <CommandName.RE_QUALIFY: 'ReQualify'>: CommandInfo(name = <CommandName.RE_QUALIFY: 'ReQualify'>, arguments=()), <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>: CommandInfo(name = <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>, arguments=()), <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>: CommandInfo(name = <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>: CommandInfo(name = <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>: CommandInfo(name = <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>: CommandInfo(name = <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>: CommandInfo(name = <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>: CommandInfo(name = <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='d', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>: CommandInfo(name = <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>: CommandInfo(name = <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>, arguments=(Parameter(name='Displacement', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>, arguments=(Parameter(name=<ParameterName.CLOSED: 'Closed'>, datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=False), Parameter(name=<ParameterName.FORMAT: 'Format'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False), Parameter(name=<ParameterName.DATA: 'Data'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.AT_NOMINALS: 'AtNominals'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False))), <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>, arguments=(Parameter(name='Deviation', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>: CommandInfo(name = <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pitch', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE: 'ScanOnLine'>: CommandInfo(name = <CommandName.SCAN_ON_LINE: 'ScanOnLine'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>: CommandInfo(name = <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>, arguments=(Parameter(name='Angle', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_PAR: 'ScanPar'>: CommandInfo(name = <CommandName.SCAN_PAR: 'ScanPar'>, arguments=()), <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>: CommandInfo(name = <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>: CommandInfo(name = <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>, arguments=(Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), )), <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>: CommandInfo(name = <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>: CommandInfo(name = <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SET_PROP: 'SetProp'>: CommandInfo(name = <CommandName.SET_PROP: 'SetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>: CommandInfo(name = <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>, arguments=(Parameter(name='Temperatures', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>: CommandInfo(name = <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>, arguments=(Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SET_TOOL: 'SetTool'>: CommandInfo(name = <CommandName.SET_TOOL: 'SetTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.START_SESSION: 'StartSession'>: CommandInfo(name = <CommandName.START_SESSION: 'StartSession'>, arguments=()), <CommandName.STEP: 'Step'>: CommandInfo(name = <CommandName.STEP: 'Step'>, arguments=(Parameter(name='Distances', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>: CommandInfo(name = <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>, arguments=()), <CommandName.STOP_DAEMON: 'StopDaemon'>: CommandInfo(name = <CommandName.STOP_DAEMON: 'StopDaemon'>, arguments=(Parameter(name='EventTag', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>: CommandInfo(name = <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>, arguments=(Parameter(name='Px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TILT_PART: 'TiltPart'>: CommandInfo(name = <CommandName.TILT_PART: 'TiltPart'>, arguments=(Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TOOL: 'Tool'>: CommandInfo(name = <CommandName.TOOL: 'Tool'>, arguments=()), <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>: CommandInfo(name = <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>, arguments=()), 'UseSmallestAngleToAlignTool': CommandInfo(name = 'UseSmallestAngleToAlignTool', arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), )), <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>: CommandInfo(name = <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>, arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), ))})) → list[FormField]

Return the inputs of name; empty without arguments (or without a schema).

catalog can come from build_command_catalog() for your own command classes.

pyippdme.client.commandform.command_names(catalog: Mapping[str, ~pyippdme.server.catalog.CommandInfo]=mappingproxy({<CommandName.ABORT_E: 'AbortE'>: CommandInfo(name=<CommandName.ABORT_E: 'AbortE'>, arguments=()), <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>: CommandInfo(name = <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>, arguments=()), <CommandName.ALIGN_PART: 'AlignPart'>: CommandInfo(name = <CommandName.ALIGN_PART: 'AlignPart'>, arguments=(Parameter(name='px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mx1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='my1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='px2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='py2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mx2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='my2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.ALIGN_TOOL: 'AlignTool'>: CommandInfo(name = <CommandName.ALIGN_TOOL: 'AlignTool'>, arguments=(Parameter(name='i1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='j2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='k2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.AVR_RADIUS: 'AvrRadius'>: CommandInfo(name = <CommandName.AVR_RADIUS: 'AvrRadius'>, arguments=()), <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>: CommandInfo(name = <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>: CommandInfo(name = <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>, arguments=(Parameter(name='Alignment', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.CENTER_PART: 'CenterPart'>: CommandInfo(name = <CommandName.CENTER_PART: 'CenterPart'>, arguments=(Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.CHANGE_TOOL: 'ChangeTool'>: CommandInfo(name = <CommandName.CHANGE_TOOL: 'ChangeTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>: CommandInfo(name = <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>, arguments=()), <CommandName.DATA_ACQUIRE: 'DataAcquire'>: CommandInfo(name = <CommandName.DATA_ACQUIRE: 'DataAcquire'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='Type', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='AcquiseSettingsName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True))), <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>: CommandInfo(name = <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), 'DeleteAcquisition': CommandInfo(name = 'DeleteAcquisition', arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>: CommandInfo(name = <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>: CommandInfo(name = <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>, arguments=()), <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>: CommandInfo(name = <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>: CommandInfo(name = <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>, arguments=()), <CommandName.DISABLE_USER: 'DisableUser'>: CommandInfo(name = <CommandName.DISABLE_USER: 'DisableUser'>, arguments=()), <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>: CommandInfo(name = <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>, arguments=()), <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>: CommandInfo(name = <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>, arguments=(Parameter(name='Bool', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), )), <CommandName.ENABLE_USER: 'EnableUser'>: CommandInfo(name = <CommandName.ENABLE_USER: 'EnableUser'>, arguments=()), <CommandName.END_SESSION: 'EndSession'>: CommandInfo(name = <CommandName.END_SESSION: 'EndSession'>, arguments=()), <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>: CommandInfo(name = <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False), )), <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>: CommandInfo(name = <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>: CommandInfo(name = <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>, arguments=()), <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>: CommandInfo(name = <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>, arguments=()), <CommandName.ENUM_PROP: 'EnumProp'>: CommandInfo(name = <CommandName.ENUM_PROP: 'EnumProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False), )), <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>: CommandInfo(name = <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.ENUM_TOOLS: 'EnumTools'>: CommandInfo(name = <CommandName.ENUM_TOOLS: 'EnumTools'>, arguments=()), <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>: CommandInfo(name = <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>, arguments=()), <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>: CommandInfo(name = <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>, arguments=None), <CommandName.FIND_TOOL: 'FindTool'>: CommandInfo(name = <CommandName.FIND_TOOL: 'FindTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.FOUND_TOOL: 'FoundTool'>: CommandInfo(name = <CommandName.FOUND_TOOL: 'FoundTool'>, arguments=()), <CommandName.GET: 'Get'>: CommandInfo(name = <CommandName.GET: 'Get'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>: CommandInfo(name = <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>: CommandInfo(name = <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>, arguments=()), <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>: CommandInfo(name = <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.GET_DME_VERSION: 'GetDMEVersion'>: CommandInfo(name = <CommandName.GET_DME_VERSION: 'GetDMEVersion'>, arguments=()), <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>: CommandInfo(name = <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>, arguments=()), <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>: CommandInfo(name = <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>, arguments=(Parameter(name='ErrorNumber', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), )), <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>: CommandInfo(name = <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>, arguments=()), <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>: CommandInfo(name = <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_PROP: 'GetProp'>: CommandInfo(name = <CommandName.GET_PROP: 'GetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_PROP_E: 'GetPropE'>: CommandInfo(name = <CommandName.GET_PROP_E: 'GetPropE'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>: CommandInfo(name = <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>: CommandInfo(name = <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>: CommandInfo(name = <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>: CommandInfo(name = <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>: CommandInfo(name = <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>, arguments=(Parameter(name='CommandName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>: CommandInfo(name = <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>, arguments=()), <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>: CommandInfo(name = <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>, arguments=()), <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>: CommandInfo(name = <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>, arguments=()), <CommandName.GO_TO: 'GoTo'>: CommandInfo(name = <CommandName.GO_TO: 'GoTo'>, arguments=(Parameter(name='Positions', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>: CommandInfo(name = <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>: CommandInfo(name = <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_PAR: 'GoToPar'>: CommandInfo(name = <CommandName.GO_TO_PAR: 'GoToPar'>, arguments=()), <CommandName.HOME: 'Home'>: CommandInfo(name = <CommandName.HOME: 'Home'>, arguments=()), <CommandName.IS_ALIGNABLE: 'IsAlignable'>: CommandInfo(name = <CommandName.IS_ALIGNABLE: 'IsAlignable'>, arguments=()), <CommandName.IS_HOMED: 'IsHomed'>: CommandInfo(name = <CommandName.IS_HOMED: 'IsHomed'>, arguments=()), <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>: CommandInfo(name = <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>, arguments=()), <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>: CommandInfo(name = <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>, arguments=()), <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>: CommandInfo(name = <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.LOCK_AXIS: 'LockAxis'>: CommandInfo(name = <CommandName.LOCK_AXIS: 'LockAxis'>, arguments=(Parameter(name='Axis', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.LOCK_POSITION: 'LockPosition'>: CommandInfo(name = <CommandName.LOCK_POSITION: 'LockPosition'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>: CommandInfo(name = <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>: CommandInfo(name = <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>: CommandInfo(name = <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ON_SCAN_REPORT: 'OnScanReport'>: CommandInfo(name = <CommandName.ON_SCAN_REPORT: 'OnScanReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>: CommandInfo(name = <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.OPT_PAR: 'OptPar'>: CommandInfo(name = <CommandName.OPT_PAR: 'OptPar'>, arguments=()), <CommandName.PT_MEAS: 'PtMeas'>: CommandInfo(name = <CommandName.PT_MEAS: 'PtMeas'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.PT_MEAS_PAR: 'PtMeasPar'>: CommandInfo(name = <CommandName.PT_MEAS_PAR: 'PtMeasPar'>, arguments=()), <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>: CommandInfo(name = <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>: CommandInfo(name = <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ROI: 'ROI'>: CommandInfo(name = <CommandName.ROI: 'ROI'>, arguments=None), <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>: CommandInfo(name = <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>, arguments=(Parameter(name='RawDataFormat', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='Port', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), Parameter(name='LiveMode', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True))), <CommandName.RE_QUALIFY: 'ReQualify'>: CommandInfo(name = <CommandName.RE_QUALIFY: 'ReQualify'>, arguments=()), <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>: CommandInfo(name = <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>, arguments=()), <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>: CommandInfo(name = <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>: CommandInfo(name = <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>: CommandInfo(name = <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>: CommandInfo(name = <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>: CommandInfo(name = <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>: CommandInfo(name = <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='d', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>: CommandInfo(name = <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>: CommandInfo(name = <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>, arguments=(Parameter(name='Displacement', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>, arguments=(Parameter(name=<ParameterName.CLOSED: 'Closed'>, datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=False), Parameter(name=<ParameterName.FORMAT: 'Format'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False), Parameter(name=<ParameterName.DATA: 'Data'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.AT_NOMINALS: 'AtNominals'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False))), <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>, arguments=(Parameter(name='Deviation', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>: CommandInfo(name = <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pitch', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE: 'ScanOnLine'>: CommandInfo(name = <CommandName.SCAN_ON_LINE: 'ScanOnLine'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>: CommandInfo(name = <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>, arguments=(Parameter(name='Angle', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_PAR: 'ScanPar'>: CommandInfo(name = <CommandName.SCAN_PAR: 'ScanPar'>, arguments=()), <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>: CommandInfo(name = <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>: CommandInfo(name = <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>, arguments=(Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), )), <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>: CommandInfo(name = <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>: CommandInfo(name = <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SET_PROP: 'SetProp'>: CommandInfo(name = <CommandName.SET_PROP: 'SetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>: CommandInfo(name = <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>, arguments=(Parameter(name='Temperatures', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>: CommandInfo(name = <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>, arguments=(Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SET_TOOL: 'SetTool'>: CommandInfo(name = <CommandName.SET_TOOL: 'SetTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.START_SESSION: 'StartSession'>: CommandInfo(name = <CommandName.START_SESSION: 'StartSession'>, arguments=()), <CommandName.STEP: 'Step'>: CommandInfo(name = <CommandName.STEP: 'Step'>, arguments=(Parameter(name='Distances', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>: CommandInfo(name = <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>, arguments=()), <CommandName.STOP_DAEMON: 'StopDaemon'>: CommandInfo(name = <CommandName.STOP_DAEMON: 'StopDaemon'>, arguments=(Parameter(name='EventTag', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>: CommandInfo(name = <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>, arguments=(Parameter(name='Px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TILT_PART: 'TiltPart'>: CommandInfo(name = <CommandName.TILT_PART: 'TiltPart'>, arguments=(Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TOOL: 'Tool'>: CommandInfo(name = <CommandName.TOOL: 'Tool'>, arguments=()), <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>: CommandInfo(name = <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>, arguments=()), 'UseSmallestAngleToAlignTool': CommandInfo(name = 'UseSmallestAngleToAlignTool', arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), )), <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>: CommandInfo(name = <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>, arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), ))})) → list[str]

All commands of catalog (default: the bundled classes), sorted.

pyippdme.client.commandform.grouped_commands(catalog: Mapping[str, ~pyippdme.server.catalog.CommandInfo]=mappingproxy({<CommandName.ABORT_E: 'AbortE'>: CommandInfo(name=<CommandName.ABORT_E: 'AbortE'>, arguments=()), <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>: CommandInfo(name = <CommandName.ADV_DATA_STRUCT: 'AdvDataStruct'>, arguments=()), <CommandName.ALIGN_PART: 'AlignPart'>: CommandInfo(name = <CommandName.ALIGN_PART: 'AlignPart'>, arguments=(Parameter(name='px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mx1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='my1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='mz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='px2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='py2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mx2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='my2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='mz2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.ALIGN_TOOL: 'AlignTool'>: CommandInfo(name = <CommandName.ALIGN_TOOL: 'AlignTool'>, arguments=(Parameter(name='i1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='j2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='k2', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True), Parameter(name='alpha', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='beta', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=True))), <CommandName.AVR_RADIUS: 'AvrRadius'>: CommandInfo(name = <CommandName.AVR_RADIUS: 'AvrRadius'>, arguments=()), <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>: CommandInfo(name = <CommandName.CALC_TOOL_ALIGNMENT: 'CalcToolAlignment'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>: CommandInfo(name = <CommandName.CALC_TOOL_ANGLES: 'CalcToolAngles'>, arguments=(Parameter(name='Alignment', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.CENTER_PART: 'CenterPart'>: CommandInfo(name = <CommandName.CENTER_PART: 'CenterPart'>, arguments=(Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.CHANGE_TOOL: 'ChangeTool'>: CommandInfo(name = <CommandName.CHANGE_TOOL: 'ChangeTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>: CommandInfo(name = <CommandName.CLEAR_ALL_ERRORS: 'ClearAllErrors'>, arguments=()), <CommandName.DATA_ACQUIRE: 'DataAcquire'>: CommandInfo(name = <CommandName.DATA_ACQUIRE: 'DataAcquire'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='Type', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='AcquiseSettingsName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True))), <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>: CommandInfo(name = <CommandName.DEL_RAW_DATA_FILE: 'DelRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), 'DeleteAcquisition': CommandInfo(name = 'DeleteAcquisition', arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>: CommandInfo(name = <CommandName.DELETE_ACQUISITION: 'DeleteAcquistion'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>: CommandInfo(name = <CommandName.DELETE_ALL_ACQUISITIONS: 'DeleteAllAcquisitions'>, arguments=()), <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>: CommandInfo(name = <CommandName.DELETE_COORD_SYSTEM: 'DeleteCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>: CommandInfo(name = <CommandName.DISABLE_OPTIMIZE: 'DisableOptimize'>, arguments=()), <CommandName.DISABLE_USER: 'DisableUser'>: CommandInfo(name = <CommandName.DISABLE_USER: 'DisableUser'>, arguments=()), <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>: CommandInfo(name = <CommandName.ENABLE_OPTIMIZE: 'EnableOptimize'>, arguments=()), <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>: CommandInfo(name = <CommandName.ENABLE_ROTARY_TABLE_VAR_CSY: 'EnableRotaryTableVarCsy'>, arguments=(Parameter(name='Bool', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), )), <CommandName.ENABLE_USER: 'EnableUser'>: CommandInfo(name = <CommandName.ENABLE_USER: 'EnableUser'>, arguments=()), <CommandName.END_SESSION: 'EndSession'>: CommandInfo(name = <CommandName.END_SESSION: 'EndSession'>, arguments=()), <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>: CommandInfo(name = <CommandName.ENUM_ALL_PROP: 'EnumAllProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False), )), <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>: CommandInfo(name = <CommandName.ENUM_ALL_TOOL_COLLECTIONS: 'EnumAllToolCollections'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>: CommandInfo(name = <CommandName.ENUM_COORD_SYSTEMS: 'EnumCoordSystems'>, arguments=()), <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>: CommandInfo(name = <CommandName.ENUM_NAME_SPACES: 'EnumNameSpaces'>, arguments=()), <CommandName.ENUM_PROP: 'EnumProp'>: CommandInfo(name = <CommandName.ENUM_PROP: 'EnumProp'>, arguments=(Parameter(name='Reference', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=False), )), <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>: CommandInfo(name = <CommandName.ENUM_TOOL_COLLECTION: 'EnumToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.ENUM_TOOLS: 'EnumTools'>: CommandInfo(name = <CommandName.ENUM_TOOLS: 'EnumTools'>, arguments=()), <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>: CommandInfo(name = <CommandName.ENUMERATE_MOVER_AXES: 'EnumerateMoverAxes'>, arguments=()), <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>: CommandInfo(name = <CommandName.FEATURE_EXTRACT: 'FeatureExtract'>, arguments=None), <CommandName.FIND_TOOL: 'FindTool'>: CommandInfo(name = <CommandName.FIND_TOOL: 'FindTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.FOUND_TOOL: 'FoundTool'>: CommandInfo(name = <CommandName.FOUND_TOOL: 'FoundTool'>, arguments=()), <CommandName.GET: 'Get'>: CommandInfo(name = <CommandName.GET: 'Get'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>: CommandInfo(name = <CommandName.GET_CHANGE_TOOL_ACTION: 'GetChangeToolAction'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>: CommandInfo(name = <CommandName.GET_COORD_SYSTEM: 'GetCoordSystem'>, arguments=()), <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>: CommandInfo(name = <CommandName.GET_CSY_TRANSFORMATION: 'GetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.GET_DME_VERSION: 'GetDMEVersion'>: CommandInfo(name = <CommandName.GET_DME_VERSION: 'GetDMEVersion'>, arguments=()), <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>: CommandInfo(name = <CommandName.GET_ERR_STATUS_E: 'GetErrStatusE'>, arguments=()), <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>: CommandInfo(name = <CommandName.GET_ERROR_INFO: 'GetErrorInfo'>, arguments=(Parameter(name='ErrorNumber', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), )), <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>: CommandInfo(name = <CommandName.GET_MACHINE_CLASS: 'GetMachineClass'>, arguments=()), <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>: CommandInfo(name = <CommandName.GET_NAMED_CSY_TRANSFORMATION: 'GetNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_PROP: 'GetProp'>: CommandInfo(name = <CommandName.GET_PROP: 'GetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_PROP_E: 'GetPropE'>: CommandInfo(name = <CommandName.GET_PROP_E: 'GetPropE'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>: CommandInfo(name = <CommandName.GET_RAW_DATA_BIN: 'GetRawDataBin'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>: CommandInfo(name = <CommandName.GET_RAW_DATA_FILE: 'GetRawDataFile'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>: CommandInfo(name = <CommandName.GET_RAW_DATA_SHA_MEM: 'GetRawDataShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>: CommandInfo(name = <CommandName.GET_SCALE_TEMPERATURES: 'GetScaleTemperatures'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>: CommandInfo(name = <CommandName.GET_SUPPORTED_ARGUMENTS: 'GetSupportedArguments'>, arguments=(Parameter(name='CommandName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>: CommandInfo(name = <CommandName.GET_SUPPORTED_COMMANDS: 'GetSupportedCommands'>, arguments=()), <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>: CommandInfo(name = <CommandName.GET_TEMPERATURE_SENSORS: 'GetTemperatureSensors'>, arguments=()), <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>: CommandInfo(name = <CommandName.GET_XTD_ERR_STATUS: 'GetXtdErrStatus'>, arguments=()), <CommandName.GO_TO: 'GoTo'>: CommandInfo(name = <CommandName.GO_TO: 'GoTo'>, arguments=(Parameter(name='Positions', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>: CommandInfo(name = <CommandName.GO_TO_ON_CIRCLE: 'GoToOnCircle'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>: CommandInfo(name = <CommandName.GO_TO_ON_SPIRAL: 'GoToOnSpiral'>, arguments=(Parameter(name='Center', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='IJK', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False))), <CommandName.GO_TO_PAR: 'GoToPar'>: CommandInfo(name = <CommandName.GO_TO_PAR: 'GoToPar'>, arguments=()), <CommandName.HOME: 'Home'>: CommandInfo(name = <CommandName.HOME: 'Home'>, arguments=()), <CommandName.IS_ALIGNABLE: 'IsAlignable'>: CommandInfo(name = <CommandName.IS_ALIGNABLE: 'IsAlignable'>, arguments=()), <CommandName.IS_HOMED: 'IsHomed'>: CommandInfo(name = <CommandName.IS_HOMED: 'IsHomed'>, arguments=()), <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>: CommandInfo(name = <CommandName.IS_OPTIMIZE_ENABLED: 'IsOptimizeEnabled'>, arguments=()), <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>: CommandInfo(name = <CommandName.IS_USER_ENABLED: 'IsUserEnabled'>, arguments=()), <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>: CommandInfo(name = <CommandName.LOAD_COORD_SYSTEM: 'LoadCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.LOCK_AXIS: 'LockAxis'>: CommandInfo(name = <CommandName.LOCK_AXIS: 'LockAxis'>, arguments=(Parameter(name='Axis', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.LOCK_POSITION: 'LockPosition'>: CommandInfo(name = <CommandName.LOCK_POSITION: 'LockPosition'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>: CommandInfo(name = <CommandName.ON_MOVE_REPORT: 'OnMoveReport'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>: CommandInfo(name = <CommandName.ON_MOVE_REPORT_E: 'OnMoveReportE'>, arguments=(Parameter(name='Time', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Dis', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=False), Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>: CommandInfo(name = <CommandName.ON_PT_MEAS_REPORT: 'OnPtMeasReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ON_SCAN_REPORT: 'OnScanReport'>: CommandInfo(name = <CommandName.ON_SCAN_REPORT: 'OnScanReport'>, arguments=(Parameter(name='Parameters', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>: CommandInfo(name = <CommandName.OPEN_TOOL_COLLECTION: 'OpenToolCollection'>, arguments=(Parameter(name='NodeName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.OPT_PAR: 'OptPar'>: CommandInfo(name = <CommandName.OPT_PAR: 'OptPar'>, arguments=()), <CommandName.PT_MEAS: 'PtMeas'>: CommandInfo(name = <CommandName.PT_MEAS: 'PtMeas'>, arguments=(Parameter(name='Axes', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.PT_MEAS_PAR: 'PtMeasPar'>: CommandInfo(name = <CommandName.PT_MEAS_PAR: 'PtMeasPar'>, arguments=()), <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>: CommandInfo(name = <CommandName.PT_MEAS_SELF_CENTER: 'PtMeasSelfCenter'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>: CommandInfo(name = <CommandName.PT_MEAS_SELF_CENTER_LOCKED: 'PtMeasSelfCenterLocked'>, arguments=(Parameter(name='Position', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.ROI: 'ROI'>: CommandInfo(name = <CommandName.ROI: 'ROI'>, arguments=None), <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>: CommandInfo(name = <CommandName.RAW_DATA_BIN_SETUP: 'RawDataBinSetup'>, arguments=(Parameter(name='RawDataFormat', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='Port', datatype=<DataType.INT: 'int'>, mandatory=True, positional=True), Parameter(name='LiveMode', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True))), <CommandName.RE_QUALIFY: 'ReQualify'>: CommandInfo(name = <CommandName.RE_QUALIFY: 'ReQualify'>, arguments=()), <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>: CommandInfo(name = <CommandName.READ_ALL_TEMPERATURES: 'ReadAllTemperatures'>, arguments=()), <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>: CommandInfo(name = <CommandName.READ_TEMPERATURE_SENSOR: 'ReadTemperatureSensor'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>: CommandInfo(name = <CommandName.RELEASE_SHA_MEM: 'ReleaseShaMem'>, arguments=(Parameter(name='AcqName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>: CommandInfo(name = <CommandName.SAVE_ACTIVE_COORD_SYSTEM: 'SaveActiveCoordSystem'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>: CommandInfo(name = <CommandName.SAVE_NAMED_CSY_TRANSFORMATION: 'SaveNamedCsyTransformation'>, arguments=(Parameter(name='Name', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>: CommandInfo(name = <CommandName.SCAN_IN_CYL_END_IS_PLANE: 'ScanInCylEndIsPlane'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>: CommandInfo(name = <CommandName.SCAN_IN_CYL_END_IS_SPHERE: 'ScanInCylEndIsSphere'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_CYL: 'ScanInPlaneEndIsCyl'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ci', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ck', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='d', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_PLANE: 'ScanInPlaneEndIsPlane'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>: CommandInfo(name = <CommandName.SCAN_IN_PLANE_END_IS_SPHERE: 'ScanInPlaneEndIsSphere'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Si', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ni', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nj', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Nk', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dia', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='n', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ei', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ej', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ek', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>: CommandInfo(name = <CommandName.SCAN_ON_CIRCLE: 'ScanOnCircle'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>: CommandInfo(name = <CommandName.SCAN_ON_CIRCLE_HINT: 'ScanOnCircleHint'>, arguments=(Parameter(name='Displacement', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE: 'ScanOnCurve'>, arguments=(Parameter(name=<ParameterName.CLOSED: 'Closed'>, datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=False), Parameter(name=<ParameterName.FORMAT: 'Format'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False), Parameter(name=<ParameterName.DATA: 'Data'>, datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False))), <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE_DENSITY: 'ScanOnCurveDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.AT_NOMINALS: 'AtNominals'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=False))), <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>: CommandInfo(name = <CommandName.SCAN_ON_CURVE_HINT: 'ScanOnCurveHint'>, arguments=(Parameter(name='Deviation', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>: CommandInfo(name = <CommandName.SCAN_ON_HELIX: 'ScanOnHelix'>, arguments=(Parameter(name='Cx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Cz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='delta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='sfa', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='pitch', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE: 'ScanOnLine'>: CommandInfo(name = <CommandName.SCAN_ON_LINE: 'ScanOnLine'>, arguments=(Parameter(name='Sx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Sz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ex', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ey', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Ez', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='i', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='j', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='k', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='StepW', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name=<ParameterName.RT: 'RT'>, datatype=<DataType.BOOL: 'bool'>, mandatory=False, positional=True))), <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>: CommandInfo(name = <CommandName.SCAN_ON_LINE_HINT: 'ScanOnLineHint'>, arguments=(Parameter(name='Angle', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Form', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SCAN_PAR: 'ScanPar'>: CommandInfo(name = <CommandName.SCAN_PAR: 'ScanPar'>, arguments=()), <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>: CommandInfo(name = <CommandName.SCAN_UNKNOWN_DENSITY: 'ScanUnknownDensity'>, arguments=(Parameter(name=<ParameterName.DIS: 'Dis'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE: 'Angle'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name=<ParameterName.ANGLE_BASE_LENGTH: 'AngleBaseLength'>, datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>: CommandInfo(name = <CommandName.SCAN_UNKNOWN_HINT: 'ScanUnknownHint'>, arguments=(Parameter(name='MinRadiusOfCurvature', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), )), <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>: CommandInfo(name = <CommandName.SET_COORD_SYSTEM: 'SetCoordSystem'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>: CommandInfo(name = <CommandName.SET_CSY_TRANSFORMATION: 'SetCsyTransformation'>, arguments=(Parameter(name='Csy', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), Parameter(name='X0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Y0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Z0', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Theta', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Psi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Phi', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.SET_PROP: 'SetProp'>: CommandInfo(name = <CommandName.SET_PROP: 'SetProp'>, arguments=(Parameter(name='Properties', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>: CommandInfo(name = <CommandName.SET_SCALE_TEMPERATURES: 'SetScaleTemperatures'>, arguments=(Parameter(name='Temperatures', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), )), <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>: CommandInfo(name = <CommandName.SET_TEMPERATURE_COMPENSATION_ORIGIN: 'SetTemperatureCompensationOrigin'>, arguments=(Parameter(name='X', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Y', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False), Parameter(name='Z', datatype=<DataType.FLOAT: 'float'>, mandatory=False, positional=False))), <CommandName.SET_TOOL: 'SetTool'>: CommandInfo(name = <CommandName.SET_TOOL: 'SetTool'>, arguments=(Parameter(name='ToolName', datatype=<DataType.STRING: 'string'>, mandatory=True, positional=True), )), <CommandName.START_SESSION: 'StartSession'>: CommandInfo(name = <CommandName.START_SESSION: 'StartSession'>, arguments=()), <CommandName.STEP: 'Step'>: CommandInfo(name = <CommandName.STEP: 'Step'>, arguments=(Parameter(name='Distances', datatype=<DataType.ENUM: 'enum'>, mandatory=True, positional=False), Parameter(name='Sync', datatype=<DataType.INT: 'int'>, mandatory=False, positional=False))), <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>: CommandInfo(name = <CommandName.STOP_ALL_DAEMONS: 'StopAllDaemons'>, arguments=()), <CommandName.STOP_DAEMON: 'StopDaemon'>: CommandInfo(name = <CommandName.STOP_DAEMON: 'StopDaemon'>, arguments=(Parameter(name='EventTag', datatype=<DataType.NAME: 'name'>, mandatory=True, positional=True), )), <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>: CommandInfo(name = <CommandName.TILT_CENTER_PART: 'TiltCenterPart'>, arguments=(Parameter(name='Px1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz1', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Px2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Py2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Pz2', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TILT_PART: 'TiltPart'>: CommandInfo(name = <CommandName.TILT_PART: 'TiltPart'>, arguments=(Parameter(name='Dx', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dy', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Dz', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True), Parameter(name='Limit', datatype=<DataType.FLOAT: 'float'>, mandatory=True, positional=True))), <CommandName.TOOL: 'Tool'>: CommandInfo(name = <CommandName.TOOL: 'Tool'>, arguments=()), <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>: CommandInfo(name = <CommandName.UPDATE_SCALE_TEMPERATURES: 'UpdateScaleTemperatures'>, arguments=()), 'UseSmallestAngleToAlignTool': CommandInfo(name = 'UseSmallestAngleToAlignTool', arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), )), <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>: CommandInfo(name = <CommandName.USE_SMALLEST_ANGLE_TO_ALIGN_TOOL: 'UseSmallestAngletoAlignTool'>, arguments=(Parameter(name='Flag', datatype=<DataType.BOOL: 'bool'>, mandatory=True, positional=True), ))})) → dict[str, list[str]]

Return the commands of catalog by group; those not in a group go to Other.

pyippdme.client.commandform.result_rows(report: Mapping[str, object]) → Iterator[tuple[str, str]]

Name/value pairs of a decoded response, for a table.

Look up what a command is, what its arguments are, and what it returns.

CommandReference is the one place a front end asks: the simple shell prints it (MetaCommands: .cmds, .man), and a GUI can show the same CommandDoc in its own widgets:

reference = CommandReference()
doc = reference.find("gOtO")            # case does not matter
doc.summary, doc.signature, doc.returns
for argument in doc.arguments:          # name, datatype, mandatory, positional, description
    ...
print(reference.manual("GoTo"))         # the same as plain text

The command catalog (names, argument types, whether an argument is optional or a bare value) comes from the bundled command classes. The descriptions are written for this package (pyippdme.client.reference_text), not taken from the standard; for a command of your own pass its description with CommandReference.describe().

class pyippdme.client.reference.ArgumentDoc(name: str, datatype: str, mandatory: bool, positional: bool, description: str)

One argument of a command.

datatype: str

float, int, bool, string, name or enum.

Type:

The wire type

positional: bool

Written as a bare value in a fixed order, not as Name(value).

class pyippdme.client.reference.CommandDoc(name: str, group: str, summary: str, notes: str, example: str, returns: str, arguments: tuple[~pyippdme.client.reference.ArgumentDoc, ...]=<factory>)

Everything known about one command.

notes: str

Longer remarks; empty when there are none.

example: str

A typical call; the signature when no better example is known.

returns: str

What the command answers with; empty when this is not known.

property signature: str

The call with its argument names; optional ones are marked with *.

class pyippdme.client.reference.CommandReference(catalog: Mapping[str, CommandInfo] | None = None, *, summaries: Mapping[str, str] | None = None)

The commands of a catalog with their descriptions.

describe(name: str, summary: str, *, notes: str = '', returns: str = '', example: str = '') → None

Add or replace the description of a command, e.g. one of your own.

names() → list[str]

Return every command name, sorted.

groups() → dict[str, list[str]]

Return the commands by task (session, move, scan, …); every command is in one.

resolve(name: str) → str | None

Return the catalog’s spelling of name (ignoring case), or None.

search(text: str) → list[str]

Return the commands whose name or summary contains text (ignoring case).

similar(name: str, limit: int = 5) → list[str]

Return command names that start like name or contain it, for a “did you mean”.

find(name: str) → CommandDoc | None

Return the description of name (case does not matter), or None.

listing(group: str | None = None) → str

Return the commands by task as text; group (a part of its name) picks some.

manual(name: str) → str

Return the manual page of name as plain text.

class pyippdme.client.reference.MetaCommands(reference: CommandReference | None = None)

The dot commands of an interactive shell: .help, .cmds, .man and .quit.

run returns the text to print, so any front end can use it:

meta = MetaCommands()
if meta.is_meta(line):
    result = meta.run(line)
    print(result.text)
    if result.quit: ...
COMMANDS = (('help', '', 'show this list'), ('cmds', '[group]', 'list the commands by task, or only one group'), ('man', '<command>', 'describe a command: arguments, return value, an example'), ('quit', '', 'leave the shell (Ctrl+D does too)'))

Name, argument hint and what it does; the order is that of .help.

classmethod names() → list[str]

Return the meta commands with their dot, e.g. .help.

classmethod is_meta(line: str) → bool

Return whether line is a meta command and not a protocol command.

run(line: str) → MetaResult

Carry out a meta command line and return what to show.

help_text() → str

Return the list of meta commands.

class pyippdme.client.reference.MetaResult(text: str = '', quit: bool = False)

What a meta command produced.

quit: bool

The user asked to leave.

Reading an optical or scanning sensor through the protocol: what it is, and what it sees.

read_sensor_info() asks the server about the active tool and how it hands over raw data (Tool.Id, Tool.AdvDataStruct). acquire() runs DataAcquire and fetches the points over the binary transfer (6.15.1, 6.17.2.1) into a ScanData. Neither needs a GUI.

class pyippdme.client.optical.SensorInfo(tool_name: str, tool_kind: str, technologies: tuple[str, ...], data_format: str)

What the server says about the active tool and its raw data.

async pyippdme.client.optical.acquire(machine: IppDmeMachine, host: str, *, name: str = 'Acq1', acquisition_type: str = 'SingleShot', settings_name: str = 'Settings', points: Sequence[AcquisitionPoint] = (), step_width: float | None = None, data_format: str = 'double', port: int | None = None, network: Network = <pyippdme.protocol.network.TcpNetwork object>, keep: bool = False) → ScanData

Acquire with the active tool and return the points, in the client’s coordinate system.

host and network are where the server’s raw-data port can be reached. Unless keep is set the acquisition is deleted on the server afterwards.

pyippdme.client.optical.bounding_box(points: NDArray[float64]) → tuple[tuple[float, float, float], tuple[float, float, float]] | None

Return the smallest and largest coordinates of a point array, or None if it is empty.

pyippdme.client.optical.path_points(start: tuple[float, float, float], end: tuple[float, float, float], count: int, *, primary: tuple[float, float, float] = (0.0, 0.0, 1.0), secondary: tuple[float, float, float] = (1.0, 0.0, 0.0)) → list[AcquisitionPoint]

count positions on the line from start to end, all with the same orientation.

async pyippdme.client.optical.read_sensor_info(machine: IppDmeMachine) → SensorInfo

Ask for the active tool and how its raw data can be fetched.

Scanning an unknown contour (6.13.2.2, Figures 35-39), and an algorithm that follows it.

The five commands ScanInPlaneEndIsSphere/EndIsPlane/EndIsCyl and ScanInCylEndIsSphere/EndIsPlane have the machine follow the real surface of a part, which the server does not know in advance, step by step from a start point in a given direction, until a stop element (sphere, plane or cylinder) is reached. The path stays in a constraint: a scanning plane (ScanInPlane) or a cylindrical surface around an axis (ScanInCyl).

ContourScan describes one such scan; a backend that can probe a surface (see scan_contour()) passes it to trace_contour(), which needs nothing but a function that probes the surface along a ray. Pure Python and numpy.

pyippdme.server.contour.SurfaceProbe

from origin along direction to (point, normal), or None. The normal points away from the material, towards the probe.

Type:

Probes the surface

alias of Callable[[tuple[float, float, float], tuple[float, float, float]], tuple[tuple[float, float, float], tuple[float, float, float]] | None]

class pyippdme.server.contour.ContourConstraint(kind: str, normal: tuple[float, float, float] | None = None, axis_point: tuple[float, float, float] | None = None, axis: tuple[float, float, float] | None = None)

What the path stays in: a plane (ScanInPlane) or a cylinder (ScanInCyl).

normal: tuple[float, float, float] | None

The scanning plane’s normal (Ni, Nj, Nk).

axis_point: tuple[float, float, float] | None

A point on the cylinder axis and its direction (Cx, Cy, Cz and Ci, Cj, Ck).

class pyippdme.server.contour.ContourStop(kind: str, point: tuple[float, float, float], direction: tuple[float, float, float] | None = None, size: float = 0.0)

What ends the scan: a sphere, a plane or a cylinder.

point: tuple[float, float, float]

Sphere centre, a point of the plane, or a point on the cylinder axis.

direction: tuple[float, float, float] | None

The plane’s normal or the cylinder’s axis direction.

size: float

The sphere’s diameter Dia or the cylinder’s diameter d.

class pyippdme.server.contour.ContourScan(constraint: ContourConstraint, start: tuple[float, float, float], probe: tuple[float, float, float], direction_point: tuple[float, float, float], step: float, stop: ContourStop, count: int = 1, end_direction: tuple[float, float, float] = (0.0, 0.0, 0.0))

One unknown-contour scan, in the coordinates of the machine it runs on.

probe: tuple[float, float, float]

from the surface towards the probe at the start.

Type:

Si, Sj, Sk

direction_point: tuple[float, float, float]

a point that gives the direction of travel from the start.

Type:

Dx, Dy, Dz

step: float

the distance between points along the path.

Type:

StepW

count: int

how often the stop element has to be reached.

Type:

n

end_direction: tuple[float, float, float]

the probing direction at the end.

Type:

Ei, Ej, Ek

pyippdme.server.contour.stop_reached(stop: ContourStop, point: tuple[float, float, float], start: tuple[float, float, float]) → bool

Whether point is in the stop element (a plane: on or beyond it, seen from the start).

class pyippdme.server.contour.StopTracker(stop: ContourStop, start: tuple[float, float, float], skip: float = 0.0, needed: int = 1)

Counts how often the stop element has been reached, as 6.13.2.2 defines it.

  • Sphere: an entry counts when the distance to the centre has a local minimum inside the sphere. If the scan starts inside, it first has to leave.

  • Plane: a pass through the plane counts, but only after the scan has moved further from the start than the direction point is (skip).

  • Cylinder: an entry into the cylinder counts. If the scan starts inside, it first has to leave.

Feed every measured point to update().

update(point: tuple[float, float, float]) → tuple[bool, bool]

Take the next measured point; return (finished, keep this point).

pyippdme.server.contour.trace_contour(scan: ContourScan, probe_surface: Callable[[tuple[float, float, float], tuple[float, float, float]], tuple[tuple[float, float, float], tuple[float, float, float]] | None], *, lookahead: float = 3.0, max_points: int = 20000, max_length: float = 10000.0) → Iterator[tuple[float, float, float]]

Follow the surface from the start until the stop element is reached; yields measured points.

At each step the surface is probed from lookahead above the nominal point, along the last known normal. The measured point and normal give the next direction of travel: tangent to the surface and inside the constraint (the intersection of the surface’s tangent plane with the scanning plane, or with the cylinder’s), continued in the sense of the previous step; the next nominal point lies one step along it. The scan ends when the stop element has been reached count times, when the surface is lost, or at max_points/max_length.

The tree of a ToolCollection (6.22, Figure 56).

A server keeps one flat list of tools. A tool collection is a tree over it: collections (nodes) hold other collections and named references to entries of the tool list, level by level (Carbody123 / EngineCompartment / X+Short). An entry of the tool list can be referenced from any number of collections, under any name, so the same qualified stylus can be X-Short for the front of one part and Y+Long for the engine compartment of another. After OpenToolCollection a client names tools by the entries of the opened collection.

Paths join node names with . as in the standard’s examples (PartXYZ.Rear); / is accepted when reading a path. The empty path is the root, whose children are level 0. Pure Python, no simulation: use it from your own server.

pyippdme.types.toolcollection.SEPARATOR = '.'

Joins the node names of a path (the examples of Tables 125-127 use PartXYZ.Rear).

pyippdme.types.toolcollection.KIND_COLLECTION = 'Collection'

The kinds an entry is reported with by EnumToolCollection.

class pyippdme.types.toolcollection.ToolRef(name: str, tool: str)

A named reference to an entry of the tool list.

class pyippdme.types.toolcollection.CollectionNode(name: str, children: list[CollectionNode | ToolRef] = <factory>)

A collection: holds collections and tool references.

pyippdme.types.toolcollection.split_path(path: str) → list[str]

Split path into node names; "" and "." are the root.

pyippdme.types.toolcollection.find_node(root: CollectionNode, path: str) → CollectionNode | None

Return the collection at path, or None (a tool reference is no node).

pyippdme.types.toolcollection.children_of(root: CollectionNode, path: str) → list[tuple[str, str]] | None

(name, kind) of the direct children at path (EnumToolCollection), or None.

pyippdme.types.toolcollection.descendants_of(root: CollectionNode, path: str) → list[tuple[str, str]] | None

(relative path, kind) of everything below path (EnumAllToolCollections).

pyippdme.types.toolcollection.resolve_tool(root: CollectionNode, open_path: str | None, name: str) → str | None

Return the tool-list entry that name stands for in the opened collection, or None.

pyippdme.types.toolcollection.add_reference(root: CollectionNode, path: str, name: str, tool: str) → None

Add tool as name in the collection at path, creating nodes on the way.

Oriented bounding boxes, as Tool.CollisionVolume() reports them (6.20.2, Figures 46-51).

The standard’s example (Figure 50) answers:

Tool.CollisionVolume(
    OBB, 100.0, 30.0, 40.0, 500.0, 15.0, 20.0,
    0.8944, 0.2683, 0.3578, -0.2873, 0.9578, 0.0, -0.3427, -0.1027, 0.9337,
    OBB, 150.0, 10.0, 530.0, 50.0, 50.0, 500.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, ...)

Each box is the token OBB and 15 numbers (Figure 46): the vector C to the centre of the box from the active tool, the extensions E of the box, and the three orthogonal unit vectors I, J, K that give its orientation, all in the coordinate system selected with SetCoordSystem/SetCsyTransformation. The rotated tool of Figure 49 gets boxes that are rotated with it.

The text does not say whether an extension is the full length or half of it. Figure 48’s box (E = 90, 95, 30 around the centre 85, 10, 20) only covers the whole star stylus that the figure draws if the extensions are half-lengths, so this package reads them that way, the usual representation of an oriented box. Pure Python.

pyippdme.types.obb.OBB_TOKEN = 'OBB'

The token that starts each box in the answer.

pyippdme.types.obb.SPH_TOKEN = 'SPH'

Precedes each sphere of Tool.AlignmentVolume (Table 118).

pyippdme.types.obb.OBB_NUMBERS = 15

C, E, I, J, K.

Type:

Numbers per box after the token

class pyippdme.types.obb.Obb(center: tuple[float, float, float], extent: tuple[float, float, float], axes: tuple[tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]])

A box with its own axes.

center: tuple[float, float, float]

the vector to the centre of the box from the active tool.

Type:

C

extent: tuple[float, float, float]

the extensions of the box along its axes, as half-lengths.

Type:

E

axes: tuple[tuple[float, float, float], tuple[float, float, float], tuple[float, float, float]]

the box’s axes as orthogonal unit vectors (the rows of the matrix).

Type:

I, J, K

numbers() → tuple[float, ...]

Return the 15 numbers of the answer: C, E, I, J, K.

mapped(direction: Callable[[tuple[float, float, float]], tuple[float, float, float]]) → Obb

Return the box with its centre vector and axes turned by direction (a rotation).