Motion Master 6.0.0-alpha.86
Next-generation motion control software
Loading...
Searching...
No Matches
mm::node Namespace Reference

Namespaces

namespace  cia402
 
namespace  profile
 
namespace  somanet
 Pure SOMANET (Synapticon manufacturer-specific) vocabulary — object indices, sub-entry numbers and enumerations, with no dependency on Device.
 

Classes

struct  BrakeState
 The brake's configuration and its current state — one read of the parts of 0x2004 that decide what a release or engage will actually do. More...
 
class  Cia402Drive
 Borrowed view of a CiA402 drive — the device control state machine, operation modes, and the standard cyclic setpoints, expressed over a Device's parameter access. More...
 
struct  Cia402Status
 A snapshot of a CiA402 drive's control state — the values a control UI needs to show at a glance: the decoded state machine state, the raw status/control words, the active operation mode (display object 0x6061), and the setpoint currently commanded for that mode. Read in one shot by Cia402Drive::readStatus. More...
 
struct  CommutationOffsetResult
 What commutation offset measurement (command 5) measured. More...
 
struct  DcSyncInfo
 A slave's live distributed-clock sync status plus its resolved device name. More...
 
class  Device
 Represents a single node on the fieldbus. More...
 
struct  DeviceDiagnosticsInfo
 A slave's live ESC health diagnostics plus its resolved device name. More...
 
struct  DeviceFile
 One file stored on a device, as its file list reports it. More...
 
class  DeviceHandle
 One device, plus the set that keeps it alive. More...
 
class  DeviceManager
 Owns the fieldbus driver and node collection, and drives PDO exchange. More...
 
struct  DeviceManagerConfig
 Runtime tuning passed to DeviceManager::init. Every field has a sensible default, so a caller can pass {} (or omit it) and override only what it cares about; new knobs can be added here without changing the init signature. More...
 
struct  DeviceParameter
 A single object dictionary entry held by a Device. More...
 
struct  DeviceSet
 One published generation of the bus: the driver that owns the socket, and the devices found on it. More...
 
struct  DeviceStateInfo
 Current AL state snapshot for a single device. More...
 
struct  DigitalOutputs
 Digital outputs (0x60FE) — commanded output levels gated by an enable mask. More...
 
struct  DumpDevice
 One device's identity and the PDO objects it contributes to the image. More...
 
struct  DumpHeader
 The embedded process-image header: everything needed to decode the rows offline. More...
 
struct  DumpPdoEntry
 One PDO-mapped object as recorded in the dump header. More...
 
struct  EncoderRegisterRequest
 What one encoder register access was asked to do. More...
 
struct  EncoderRegisterResult
 What one encoder register access did — the result of both a read and a write, since the drive answers a write by echoing back the register's value. More...
 
struct  EniCollection
 A collected network, and what could not be read while collecting it. More...
 
struct  EniCollectorOptions
 What an ENI needs that no device can answer for. More...
 
struct  FeedConstant
 Feed constant (0x6092) — feed (position units) per driving shaft revolutions. More...
 
struct  FirmwareCompatibility
 The verdict on one package against one device. More...
 
struct  FirmwareInstallationRequest
 Where an install leaves the device, as an AL state. More...
 
struct  FirmwareLatencyRequest
 What one firmware latency run was asked to do. More...
 
struct  FirmwareLatencyResult
 The maximum one firmware latency reached, as command 22 reported it. More...
 
struct  FirmwarePackage
 A firmware package's contents, sorted by where each entry is going. More...
 
struct  FirmwarePackageFile
 One entry of a package, extracted. More...
 
struct  FirmwarePackageName
 A SOMANET firmware package filename, broken into the five fields the naming convention defines (Hardware description specification §3.4.2). More...
 
struct  FlatPdoMapping
 A device's complete PDO mapping across both directions. More...
 
struct  FullFirmwareDescriptors
 The full firmware descriptors one device accepts firmware under (specification §3.4.1). More...
 
struct  GearRatio
 Gear ratio (0x6091) — motor revolutions per driving shaft revolutions. More...
 
struct  HardwareComponent
 One item making up a device or assembly (specification §3.2.2.3). More...
 
struct  HardwareDescription
 A parsed .hardware_description file (specification §3.2). More...
 
struct  HardwareProduct
 A device or an assembly — the two are one shape (specification §3.2.2). More...
 
struct  HomingSpeeds
 Homing speeds (0x6099) — the two velocities of a homing run. More...
 
struct  HrdEncoderSample
 One sample of somanet::HrdData::kEncoderRawData. More...
 
struct  HrdRecording
 One high resolution data recording, read back from the drive's files and decoded. More...
 
struct  HrdStreamingRequest
 What one high resolution data recording was asked to capture. More...
 
struct  HrdSystemIdentificationSample
 One sample of somanet::HrdData::kSystemIdentificationData. More...
 
struct  IcMuCalibrationModeRequest
 What one iC-MU calibration mode change was asked to do. More...
 
struct  Identity
 The CANopen identity object (0x1018) — the four UNSIGNED32 sub-entries that uniquely identify a device on the bus. More...
 
struct  IgnoreBissStatusBitsRequest
 Which encoder's status bits to act on, and which way. More...
 
struct  IntegroVariant
 A parsed .variant file. More...
 
struct  IntegroVariantOption
 One entry of the Integro runtime-variant option catalogue. More...
 
struct  KueblerRegisterRequest
 What one Kübler register access was asked to do. More...
 
struct  KueblerRegisterResult
 What one Kübler register access produced (command 19). More...
 
struct  MonitoredParameter
 One object a monitoring samples, addressed by bus position and CoE index. More...
 
struct  Monitoring
 A client-defined recording of a set of parameters streamed over time. More...
 
class  MonitoringManager
 Owns the active monitorings and turns each into a lossless stream of recorded rows. More...
 
struct  MotorPhaseOrderResult
 What motor phase order detection (command 4) found. More...
 
class  NotificationBus
 Polls a fixed set of sources and broadcasts a notification when one of them changes. More...
 
struct  ObjectAddress
 The address of one object-dictionary entry, carrying the type that entry holds. More...
 
struct  ObjectDictionaryValue
 One object dictionary entry, as OS command 21 delivered it. More...
 
struct  ObjectDictionaryValues
 Every object dictionary value the drive holds, read in one transfer by OS command 21. More...
 
struct  ObjectValues
 Decoded values of one object's readable sub-entries, as returned by Device::readObject. More...
 
struct  OpenPhaseResult
 What open phase detection found. More...
 
struct  OperationModeInfo
 One operation mode of one device. More...
 
struct  OperationModes
 Every operation mode of one device, with what the drive says about each. More...
 
struct  OsCommandConfig
 Timing and cancellation for SomanetDrive::runOsCommand. More...
 
struct  OsCommandFsBuffer
 An OS command's fs-buffer transfer — the data that does not fit in the 8 command bytes. More...
 
struct  OsCommandRequest
 What one raw OS command run was asked to do. More...
 
struct  OsCommandResponse
 A completed OS command's response — the decoded form of 0x1023:03. More...
 
struct  OsCommandResult
 What one raw OS command run produced — the step's value. More...
 
struct  OutputStageRequest
 One object to stage into the output process image, as parsed from a batch write request. More...
 
struct  OutputStageResult
 Per-object outcome of a batch output stage. More...
 
class  ParameterCache
 On-disk cache of CoE parameter definitions, keyed by device identity. More...
 
struct  ParameterCacheConfig
 Policy and location for the on-disk parameter cache. More...
 
struct  ParameterOption
 One choice of a kEnum parameter: the value that goes on the wire, and its label. More...
 
class  ParameterRefresher
 Keeps a reference-counted set of SDO parameters fresh by polling them off-thread. More...
 
struct  PdoMapping
 A device's desired PDO configuration to write and assign — the write-side input to Device::writePdoMapping, and the grouped counterpart of the read-side FlatPdoMapping. More...
 
struct  PdoMappingEntry
 One object mapped into a slave's process data, with its position in the window. More...
 
struct  PdoMappingObject
 One PDO mapping object (0x16xx RxPDO / 0x1Axx TxPDO) and its ordered entries. More...
 
struct  PhaseInductanceResult
 What phase inductance measurement (command 9) measured. More...
 
struct  PhaseResistanceResult
 What phase resistance measurement (command 8) measured. More...
 
struct  PolePairResult
 What pole pair detection (command 7) found. More...
 
struct  PositionRangeLimit
 Position range limit (0x607B) — the range position values wrap around in. More...
 
struct  ProcedureCatalogueEntry
 One procedure, as the catalogue knows it: what it is, who has it, and how to run it. More...
 
struct  ProcedureContext
 What a procedure body is given: the device it runs on, and the manager that owns it. More...
 
struct  ProcedureDescriptor
 What a procedure is, independent of any run — the half of the catalogue a client needs to render a control for it. More...
 
struct  ProcedureError
 Why a procedure operation could not be performed. A caller must branch on this — an HTTP handler maps each kind to a different status — which is what earns a structured error here rather than the usual std::string (see CLAUDE.md's no-exceptions mandate, and libs/comm/foe_error.h for the shape). It keeps a string face so forwarding callers are unaffected. More...
 
struct  ProcedureListing
 One procedure paired with how its last run on a device went — an entry of GET /api/devices/:pos/procedures. More...
 
class  ProcedureManager
 Runs off-RT command-and-wait procedures and remembers how each one went. More...
 
struct  ProcedureParameter
 One named parameter a procedure accepts — enough for a client to render a field for it and for a user to know what to put in. More...
 
struct  ProcedureSnapshot
 The complete state of a procedure on one device — everything a client polling GET /api/devices/:pos/procedures/:name receives. More...
 
struct  ProcessBuffer
 Fixed-capacity byte buffer for one direction of the process image. More...
 
struct  ProcessData
 The live process-data runtime: the published image, the cross-thread exchange buffers, and per-object PDO access over them. More...
 
class  ProcessDataCyclicTask
 Game-loop task that exchanges one cycle of process data. More...
 
class  ProcessDataRing
 A lock-free circular recorder of the raw process image, one record per RT cycle. More...
 
struct  ProcessImage
 The whole bus's process-data layout, resolved to absolute positions. More...
 
struct  ProcessImageEntry
 Locates one mapped object within the flat process image. More...
 
struct  ProcessImageInfo
 API-facing snapshot of the currently published process image and its runtime health. More...
 
struct  ProcessImageObjectInfo
 One mapped object in the published process image, with its name resolved. More...
 
class  ProfileDevice
 Root of the drive-profile view hierarchy — a concrete, instantiable, borrowed view over a Device that exposes the generic CANopen device area (CiA301). More...
 
class  ProgressReporter
 The handle a procedure body uses to report where it has got to. More...
 
struct  ProgressStep
 One step of a procedure — an entry in the fixed, ordered array a procedure publishes. More...
 
struct  RestoreDefaultParameters
 The restore-default-parameters object (0x1011) — one UNSIGNED32 per restorable group. Reading a sub-entry reports the restore capability (bit 0 = device restores on command); writing the "load" signature to it triggers the restore. More...
 
struct  RestoreDefaultParametersConfig
 Retry/timing for the restore-default-parameters confirmation walk (ProfileDevice::runRestoreDefaultParameters). More...
 
struct  RestoreDefaultParametersRequest
 What one restore was asked to do. More...
 
struct  ScalarCell
 One scalar value, and the only part of a DeviceParameter that two threads touch at once. More...
 
struct  SkippedCyclesRequest
 Which control loop's counter to read. More...
 
struct  SkippedCyclesResult
 What the skipped cycles counter (command 13) reported for one control loop. More...
 
struct  SlaveConfigInfo
 A slave's static ESC configuration plus its resolved device name. More...
 
struct  SoftwarePositionLimit
 Software position limit (0x607D) — the absolute end stops enforced in software. More...
 
class  SomanetDrive
 Borrowed view of a SOMANET drive — a CiA402 drive plus Synapticon-specific object-dictionary access (encoder/motor configuration, custom OS commands, etc.). More...
 
struct  StoreParametersConfig
 Timing for the store-parameters confirmation walk (ProfileDevice::runStoreParameters). More...
 
struct  SystemIdentificationRequest
 One system identification run, as a client describes it. More...
 
struct  TorqueConstantResult
 What torque constant measurement (command 10) measured. More...
 
struct  TriggerErrorRequest
 Which service to break, and how. More...
 
struct  TriggerErrorResult
 What one trigger-error run did (command 16). More...
 
struct  VelocitySourceRequest
 Which velocity the control loop should use. More...
 

Typedefs

using DeviceParameterValue = std::variant< int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t, float, double, std::string, std::vector< uint8_t > >
 Decoded value of a single device parameter (CoE object dictionary entry).
 
using ProcedureBody = std::function< std::expected< void, std::string >(const ProcedureContext &, ProgressReporter &, std::stop_token)>
 A procedure's work: everything one run does, as a plain callable.
 
using DumpRecordReader = std::function< bool(uint64_t seq, ProcessDataRing::Record &out)>
 Reads the record for seq into out; returns false if it is no longer available (lapped or a torn read). Wraps ProcessDataRing::readRecord.
 
using HrdSamples = std::variant< std::vector< HrdEncoderSample >, std::vector< HrdSystemIdentificationSample > >
 A decoded recording's samples: exactly one vector, whichever the data selection implies.
 

Enumerations

enum class  Cia402Command { kEnable , kDisable , kQuickStop , kFaultReset }
 High-level state-machine actions a client can command (the named transitions a UI exposes as buttons). Distinct from cia402::Command (raw controlword bit patterns). More...
 
enum class  Cia402TargetKind { kPosition , kVelocity , kTorque }
 Which cyclic setpoint a target write addresses. Exactly one is active at a time — the one matching the drive's operation mode (position for PP/CSP, velocity for PV/CSV, torque for PT/CST) — so a target write names its kind rather than setting all three. More...
 
enum class  CompleteAccessSupport : uint8_t { kUnknown , kSupported , kUnsupported }
 Runtime discovery state of CoE Complete Access support. CA is optional in CoE and the EEPROM capability hint is unreliable (SOMANET advertises completeAccess=false while CA in fact works), so support is probed: the first grouped read attempts CA and the outcome is remembered — the runtime probe, not the hint, is authoritative. More...
 
enum class  DeclaredSubindexReads : uint8_t { kUnknown , kServed , kRefused }
 Whether a device serves the subindices an array or a record declares but does not hold. More...
 
enum class  SyncState : uint8_t { Unknown , Synced , Pending }
 Tracks how a cached parameter value relates to the device. More...
 
enum class  ParameterOrigin : uint8_t { ObjectDictionary , Sii }
 Where a parameter's definition (schema/metadata) came from. More...
 
enum class  FirmwareMatch { kNone , kAssembly , kDevice }
 Which of a device's descriptors a package matched. More...
 
enum class  VariantOperationMode : uint16_t { kPassive = 0x51 , kTrial = 0x53 , kProduction = 0x55 , kLive = 0x57 }
 How the drive treats its variant options (firmware OPTIONS_MODE_*). More...
 
enum class  OperationModeKind : uint8_t { kStandard , kManufacturer }
 Where a mode is defined, which is also how much can be said about it. More...
 
enum class  ProgressStatus : uint8_t { kIdle , kRunning , kSucceeded , kFailed }
 Status of one step within a procedure. More...
 
enum class  ProcedureStatus : uint8_t {
  kIdle , kRunning , kSucceeded , kFailed ,
  kCancelled
}
 Overall status of a procedure run — the single field a polling client checks. More...
 
enum class  ParameterType : uint8_t {
  kInteger , kBoolean , kEnum , kByteArray ,
  kString , kStringArray , kFile
}
 What kind of value a procedure parameter takes — the client's cue for which control to render, and the only vocabulary a generic form has to understand. More...
 
enum  GenericObject : uint16_t {
  kDeviceType = 0x1000 , kErrorRegister = 0x1001 , kCobIdSync = 0x1005 , kCommunicationCyclePeriod = 0x1006 ,
  kManufacturerDeviceName = 0x1008 , kManufacturerSoftwareVersion = 0x100A , kGuardTime = 0x100C , kLifeTimeFactor = 0x100D ,
  kStoreParameters = 0x1010 , kRestoreDefaultParameters = 0x1011 , kConsumerHeartbeatTime = 0x1016 , kProducerHeartbeatTime = 0x1017 ,
  kIdentity = 0x1018 , kSynchronousCounterOverflowValue = 0x1019 , kOsCommand = 0x1023 , kOsCommandMode = 0x1024
}
 Generic CANopen device-profile (CiA301) object indices — present on any CoE device, independent of the CiA402 drive profile. Simple VAR objects are addressed at subindex 0; RECORD objects (0x1010, 0x1011, 0x1016, 0x1018, 0x1023) at their documented sub-entries. More...
 
enum class  RestoreGroup : uint8_t { kAll = 1 , kCommunication = 2 , kApplication = 3 , kManufacturer = 4 }
 Which group of default parameters to restore (which 0x1011 sub-entry to command). The enum value is the sub-entry number, so it maps straight to the object subindex. More...
 
enum class  OsCommandStatus : uint8_t { kCompleted = 0 , kCompletedWithData = 1 , kFailed = 2 , kFailedWithData = 3 }
 Terminal OS command status — byte 0 of the response (0x1023:03), which the firmware mirrors from 0x1023:02. Only these four values end a command; 100-200 (executing, with percentage) and 255 (executing) are transient and never surface to a caller. More...
 
enum class  OsCommandError : uint8_t {
  kNotAllowed = 251 , kAborted = 252 , kTimeout = 253 , kUnsupported = 254 ,
  kReserved = 255
}
 The general OS error codes — the ones any command can report, counting down from 254. Command-specific codes count up from 0 and are named by the command that issued them, not here (open phase detection's 0 is "open terminal A", phase resistance's 0 is "current amplitude error", ...). More...
 
enum class  FsBufferTransfer : uint8_t { kNone , kRead , kWrite }
 Which way an OS command's fs-buffer transfer moves bytes. More...
 
enum class  FirmwareLatencyAction : uint8_t { kMeasure , kStart , kReadMaximum , kStop }
 What one firmware latency run should do. More...
 
enum class  SomanetProduct : uint32_t { kNode = 0x00000201 , kCirculo = 0x00000301 , kCirculoSmm = 0x00000302 , kIntegro = 0x00000401 }
 Known SOMANET product codes (object 0x1018:02) under kSynapticonVendorId. More...
 

Functions

std::expected< Cia402Status, std::string > cia402Status (DeviceManager &deviceManager, uint16_t slavePosition)
 Reads a device's CiA402 control snapshot (state, status/control words, active mode).
 
std::expected< Cia402Status, std::string > setCia402OperationMode (DeviceManager &deviceManager, uint16_t slavePosition, int8_t mode, std::chrono::milliseconds timeout=std::chrono::milliseconds(200))
 Requests an operation mode (0x6060) by its raw value, then reads back the snapshot.
 
std::expected< Cia402Status, std::string > runCia402Command (DeviceManager &deviceManager, uint16_t slavePosition, Cia402Command command, std::chrono::milliseconds timeout=std::chrono::milliseconds(2000))
 Runs a CiA402 state-machine command (enable / disable / quick stop / fault reset), then reads back the resulting snapshot.
 
std::expected< Cia402Status, std::string > transitionToCia402State (DeviceManager &deviceManager, uint16_t slavePosition, cia402::State target, std::chrono::milliseconds timeout=std::chrono::milliseconds(2000))
 Brings a drive to target, walking whatever transitions that takes, then reads back the resulting snapshot.
 
std::expected< void, std::string > setCia402Target (DeviceManager &deviceManager, uint16_t slavePosition, Cia402TargetKind kind, int32_t setpoint)
 Writes the one CiA402 cyclic setpoint that matches the active operation mode.
 
void to_json (nlohmann::json &j, const Cia402Status &s)
 Serialises a Cia402Status. Emits state/modeName as human-readable strings alongside the numeric statusword, controlword, and modeOfOperation.
 
std::optional< Cia402CommandparseCia402Command (std::string_view token)
 Parses a command token ("enable" / "disable" / "quickStop" / "faultReset").
 
std::optional< Cia402TargetKindparseCia402TargetKind (std::string_view token)
 Parses a target-kind token ("position" / "velocity" / "torque").
 
std::expected< Cia402Drive, std::string > createCia402Drive (Device &device)
 Validates that device implements the CiA402 profile, then binds a view to it.
 
void to_json (nlohmann::json &j, const Device &d)
 Serialises a Device to JSON.
 
std::expected< int, std::string > reconcileDetectedModules (const Device &device)
 Reconciles a device's Configured Module Ident List with its Detected list.
 
void to_json (nlohmann::json &j, const DeviceStateInfo &info)
 Serialises a DeviceStateInfo to JSON.
 
void to_json (nlohmann::json &j, const OutputStageResult &result)
 Serialises an OutputStageResult to JSON.
 
void to_json (nlohmann::json &j, const ProcessImageObjectInfo &obj)
 Serialises a ProcessImageObjectInfo to JSON.
 
void to_json (nlohmann::json &j, const ProcessImageInfo &info)
 Serialises a ProcessImageInfo to JSON.
 
void to_json (nlohmann::json &j, const SlaveConfigInfo &info)
 Serialises a SlaveConfigInfo (and its nested SM/FMMU/mailbox/DC) to JSON.
 
void to_json (nlohmann::json &j, const DeviceDiagnosticsInfo &info)
 Serialises a DeviceDiagnosticsInfo (and its nested per-port counters) to JSON.
 
void to_json (nlohmann::json &j, const DcSyncInfo &info)
 Serialises a DcSyncInfo to JSON.
 
void to_json (nlohmann::json &j, const DeviceManager &dm)
 Serialises all devices in a DeviceManager to a JSON array.
 
std::unexpected< std::string > deviceNotFound (uint16_t slavePosition)
 The error to return when a bus position resolves to no device.
 
DeviceParameterValue defaultValueForDataType (uint16_t dataType)
 Returns a zero-equivalent value for the given ETG.1020 dataType.
 
bool isScalarDataType (uint16_t dataType)
 Whether a value of dataType is stored in DeviceParameter::bits.
 
size_t scalarByteWidth (uint16_t dataType)
 Width in bytes of a value of dataType, or 0 when it is not a scalar.
 
uint64_t packLeBits (std::span< const uint8_t > bytes)
 Packs up to eight raw little-endian wire bytes into a uint64_t (zero-extended).
 
void unpackLeBits (uint64_t bits, std::span< uint8_t > out)
 Unpacks bits into out, little-endian. The inverse of packLeBits.
 
std::expected< DeviceParameterValue, std::string > decodeSdoBytes (uint16_t dataType, std::span< const uint8_t > bytes)
 Decodes a raw SDO byte sequence according to an ETG.1020 data type code.
 
std::expected< std::vector< uint8_t >, std::string > encodeSdoBytes (uint16_t dataType, const DeviceParameterValue &value)
 Serialises a DeviceParameterValue to raw SDO bytes — the inverse of decodeSdoBytes.
 
std::optional< double > numericValue (const DeviceParameterValue &value)
 Coerces a DeviceParameterValue to a double, when it holds a number.
 
std::string_view syncStateName (SyncState state)
 Returns the lowercase string form of state ("unknown" etc.).
 
std::string_view parameterOriginName (ParameterOrigin origin)
 Returns the string form of origin ("objectDictionary" / "sii").
 
void to_json (nlohmann::json &j, const DeviceParameter &p)
 Serialises a DeviceParameter to JSON.
 
constexpr uint32_t makeParameterKey (uint16_t index, uint8_t subindex)
 Packs an object dictionary index and subindex into a single 32-bit key.
 
std::expected< EniCollection, std::string > collectEni (DeviceManager &manager, const EniCollectorOptions &options)
 Reads the live bus and builds an ENI network from it.
 
std::expected< nlohmann::json, std::string > buildEniResponse (std::string_view xml)
 Reads an ENI document and renders it as JSON, with each datagram explained.
 
std::expected< FirmwarePackageName, std::string > parseFirmwarePackageName (std::string_view filename)
 Decodes filename as a SOMANET firmware package name.
 
std::expected< FirmwarePackage, std::string > openFirmwarePackage (std::span< const uint8_t > zip, std::span< const std::string > skipFiles)
 Reads a firmware package zip held in memory, dropping the entries named in skipFiles.
 
void to_json (nlohmann::json &j, const FirmwarePackageName &name)
 Serialises a decoded package name — the body of GET /api/firmware-package-name.
 
FullFirmwareDescriptors fullFirmwareDescriptors (const HardwareDescription &description, const IntegroVariant *variant)
 Assembles the descriptors description accepts, appending variant's fieldbus character when there is one.
 
std::string_view toString (FirmwareMatch match)
 What a match is called, for a message or a JSON body: "none", "assembly", "device".
 
FirmwareCompatibility checkFirmwareCompatibility (const HardwareDescription &description, const FirmwarePackageName &packageName, const IntegroVariant *variant=nullptr)
 Decides whether packageName belongs on the hardware description describes.
 
std::expected< FirmwareCompatibility, std::string > checkFirmwareCompatibility (std::string_view hardwareDescriptionContent, std::string_view packageFilename, const IntegroVariant *variant=nullptr)
 Parses both inputs, then decides — the whole check from a file's text and a filename.
 
std::expected< HardwareDescription, std::string > parseHardwareDescription (std::string_view content)
 Decodes content as a .hardware_description file.
 
std::string_view toString (VariantOperationMode mode)
 The mode's name, or "unknown" for a value no firmware release defines.
 
std::span< const IntegroVariantOptionintegroVariantOptions ()
 The whole catalogue, in code order.
 
const IntegroVariantOptionintegroVariantOption (uint16_t id)
 Looks a code up in the catalogue.
 
void to_json (nlohmann::json &j, const IntegroVariantOption &option)
 Serialises one catalogue entry — the body of GET /api/integro-variant/options.
 
std::expected< IntegroVariant, std::string > parseIntegroVariant (std::span< const uint8_t > content)
 Decodes content as a .variant file.
 
std::optional< uint16_t > variantFieldbusProtocol (const IntegroVariant &variant)
 The selected fieldbus protocol, for the tail of a full firmware descriptor (specification §3.4.2.1).
 
void to_json (nlohmann::json &j, const IntegroVariant &variant)
 Serialises a parsed file.
 
void to_json (nlohmann::json &j, const MonitoredParameter &p)
 Serialises a MonitoredParameter to JSON: {devicePosition, index, subindex}.
 
void to_json (nlohmann::json &j, const Monitoring &m)
 Serialises a Monitoring to JSON: {topic, name?, interval, parameters}.
 
void to_json (nlohmann::json &j, const OperationModes &modes)
 
std::expected< OperationModes, std::string > deviceOperationModes (Device &device)
 Builds the operation-mode table for device.
 
std::expected< OperationModes, std::string > operationModes (DeviceManager &deviceManager, uint16_t slavePosition)
 Borrow-and-delegate wrapper over deviceOperationModes, for a caller holding a bus position rather than a device (the HTTP layer).
 
void to_json (nlohmann::json &j, const ParameterCache::CacheEntry &e)
 Serialises a CacheEntry to JSON (keys: vendorId, productCode, revisionNumber, parameterCount, sizeBytes). Participates in nlohmann ADL.
 
void to_json (nlohmann::json &j, const PdoMappingEntry &e)
 Serialises a single entry: index, subindex, bitLength, bitOffset.
 
void to_json (nlohmann::json &j, const PdoMappingObject &o)
 Serialises one mapping object: pdoIndex and its ordered entries.
 
void to_json (nlohmann::json &j, const PdoMapping &m)
 Serialises a device's grouped mapping: outputs / inputs object arrays. The response shape of the PDO-mapping routes (each entry carries its derived bitOffset).
 
uint32_t packMappingEntry (const PdoMappingEntry &e)
 Packs an entry into its 32-bit CoE mapping word (ETG.1000.6 §5.6.7.4.7): index<<16 | subindex<<8 | bitLength.
 
PdoMappingEntry unpackMappingEntry (uint32_t packed)
 Unpacks a 32-bit CoE mapping word into an entry — the inverse of packMappingEntry.
 
void to_json (nlohmann::json &j, const ProgressStep &step)
 
std::vector< ProgressStepstepsFrom (std::initializer_list< std::string_view > ids)
 A procedure's step template: the given ids, in order, all idle.
 
ProcedureSnapshot idleSnapshot (std::vector< ProgressStep > steps)
 A well-formed snapshot for a procedure that never ran — idle, no timestamps, and every step idle from steps.
 
void to_json (nlohmann::json &j, const ProcedureSnapshot &snapshot)
 
void to_json (nlohmann::json &j, const ParameterOption &option)
 
void to_json (nlohmann::json &j, const ProcedureParameter &parameter)
 
ProcedureParameter integerParameter (std::string name, std::string title, std::string description, nlohmann::json defaultValue, int64_t minValue, int64_t maxValue)
 A whole-number parameter accepting minValue to maxValue inclusive.
 
ProcedureParameter booleanParameter (std::string name, std::string title, std::string description, nlohmann::json defaultValue)
 A true/false parameter. defaultValue as in integerParameter.
 
ProcedureParameter enumParameter (std::string name, std::string title, std::string description, nlohmann::json defaultValue, std::vector< ParameterOption > options)
 A parameter whose value is one of options. defaultValue as in integerParameter, and it should be one of the option values.
 
ProcedureParameter byteArrayParameter (std::string name, std::string title, std::string description, size_t length)
 A parameter taking exactly length byte values.
 
ProcedureParameter stringParameter (std::string name, std::string title, std::string description, nlohmann::json defaultValue)
 A free-text parameter. defaultValue as in integerParameter.
 
ProcedureParameter stringArrayParameter (std::string name, std::string title, std::string description, nlohmann::json defaultValue)
 A parameter taking a list of strings, which the client renders as an editable list.
 
ProcedureParameter fileParameter (std::string name, std::string title, std::string description, nlohmann::json defaultValue)
 A parameter carrying a whole file, base64-encoded in a JSON string.
 
void to_json (nlohmann::json &j, const ProcedureDescriptor &descriptor)
 
constexpr std::string_view toString (ProgressStatus status)
 Human-readable name of a step status (for logging / JSON). Never returns nullptr.
 
constexpr std::string_view toString (ProcedureStatus status)
 Human-readable name of a procedure status (for logging / JSON). Never nullptr.
 
constexpr std::string_view toString (ParameterType type)
 Human-readable name of a parameter type (for JSON). Never returns nullptr.
 
const std::vector< ProcedureCatalogueEntry > & procedureCatalogue ()
 Every procedure the server knows, in the order a client should present them.
 
void to_json (nlohmann::json &j, const ProcedureListing &listing)
 
std::expected< std::vector< ProcedureListing >, ProcedureErrorlistProcedures (DeviceManager &deviceManager, ProcedureManager &procedureManager, uint16_t devicePosition)
 Every procedure devicePosition supports, each with its current or last-run snapshot.
 
std::expected< ProcedureSnapshot, ProcedureErrorprocedureSnapshot (DeviceManager &deviceManager, ProcedureManager &procedureManager, uint16_t devicePosition, std::string_view name)
 The current or last-run state of one procedure on one device.
 
std::expected< ProcedureSnapshot, ProcedureErrorstartProcedure (DeviceManager &deviceManager, ProcedureManager &procedureManager, uint16_t devicePosition, std::string_view name, const nlohmann::json &request)
 Starts name on devicePosition with request as its parameters.
 
std::expected< void, ProcedureErrorcancelProcedure (DeviceManager &deviceManager, ProcedureManager &procedureManager, uint16_t devicePosition, std::string_view name)
 Asks the running name on devicePosition to stop.
 
std::ostream & operator<< (std::ostream &os, const ProcedureError &e)
 Streams the message, so ASSERT_TRUE(r) << r.error() and spdlog {} work unchanged.
 
std::expected< uint64_t, std::string > writeProcessDataDump (std::ostream &out, const DumpHeader &header, uint64_t startSeq, uint64_t endSeq, const DumpRecordReader &read)
 Serialises the frozen span [startSeq, endSeq) to out as a .mmpd dump.
 
std::expected< ProcessImage, std::string > buildProcessImage (const mm::comm::PdoLayout &layout, const std::vector< Device > &devices)
 Assembles a ProcessImage from the driver layout and per-device PDO mappings.
 
void extractBits (std::span< const uint8_t > src, uint32_t bitOffset, uint16_t bitLength, std::span< uint8_t > out)
 Extracts bitLength bits at bitOffset from src into the caller's out buffer.
 
std::vector< uint8_t > extractBits (std::span< const uint8_t > src, uint32_t bitOffset, uint16_t bitLength)
 Extracts bitLength bits at bitOffset from src into a fresh LSB-aligned little-endian byte vector (ceil(bitLength/8) bytes), as the SDO encoding would.
 
void insertBits (std::span< uint8_t > dst, uint32_t bitOffset, uint16_t bitLength, std::span< const uint8_t > value)
 Inserts bitLength bits of value (LSB-first) into dst at bitOffset.
 
std::optional< RestoreGroupparseRestoreGroup (std::string_view token)
 Parses a restore-group token ("all" / "communication" / "application" / "manufacturer") into a RestoreGroup. Returns std::nullopt for any other token.
 
std::expected< ProfileDevice, std::string > createProfileDevice (Device &device)
 Binds a generic device-profile view to device.
 
constexpr std::string_view toString (RestoreGroup group)
 The token naming group — the inverse of parseRestoreGroup, and the form the group takes on the wire. Never returns nullptr.
 
std::vector< ProgressStepstoreParametersSteps ()
 Store parameters' step template — one step, idle.
 
std::expected< void, std::string > runStoreParametersProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, StoreParametersConfig config={})
 Runs a parameter store (0x1010) as a procedure body.
 
std::expected< RestoreDefaultParametersRequest, std::string > parseRestoreDefaultParametersRequest (const nlohmann::json &body)
 Parses and validates a client's restore request body.
 
std::vector< ProcedureParameterrestoreDefaultParametersParameters ()
 What restoring default parameters accepts, as its descriptor advertises it.
 
std::vector< ProgressSteprestoreDefaultParametersSteps ()
 Restore default parameters' step template — one step, idle.
 
std::expected< void, std::string > runRestoreDefaultParametersProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const RestoreDefaultParametersRequest &request, RestoreDefaultParametersConfig config={})
 Runs a restore of default parameters (0x1011) as a procedure body.
 
std::expected< BrakeState, std::string > brakeState (DeviceManager &deviceManager, uint16_t slavePosition)
 Reads a drive's brake configuration and current state (0x2004).
 
std::expected< BrakeState, std::string > releaseBrake (DeviceManager &deviceManager, uint16_t slavePosition, std::chrono::milliseconds settle)
 Releases (disengages) a drive's brake, then waits for the release to finish.
 
std::expected< BrakeState, std::string > engageBrake (DeviceManager &deviceManager, uint16_t slavePosition, std::chrono::milliseconds settle)
 Engages a drive's brake and waits settle for it to bite.
 
std::expected< std::vector< DeviceFile >, std::string > readFileList (DeviceManager &deviceManager, uint16_t slavePosition)
 Reads the list of files stored on a device (FoE read of "fs-getlist").
 
std::expected< void, std::string > removeFile (DeviceManager &deviceManager, uint16_t slavePosition, const std::string &filename)
 Deletes one file from a device's flash.
 
std::expected< HardwareDescription, std::string > readHardwareDescription (DeviceManager &deviceManager, uint16_t slavePosition)
 Reads and parses a device's .hardware_description file.
 
std::expected< std::optional< IntegroVariant >, std::string > readIntegroVariant (DeviceManager &deviceManager, uint16_t slavePosition)
 Reads and parses a device's .variant file.
 
std::expected< FirmwareCompatibility, std::string > checkFirmwarePackage (DeviceManager &deviceManager, uint16_t slavePosition, std::string_view packageFilename)
 Reads what a device is and decides whether a firmware package belongs on it.
 
std::expected< HrdRecording, std::string > readHrdRecording (DeviceManager &deviceManager, uint16_t slavePosition, somanet::HrdData data)
 Reads a drive's high resolution data recording back and decodes it.
 
std::optional< FsBufferTransferparseFsBufferTransfer (std::string_view token)
 Reads an fs-buffer direction back from its name. std::nullopt if token names none.
 
std::optional< std::string_view > osCommandErrorName (uint8_t code)
 Names a general OS error code, or std::nullopt when code is command-specific.
 
void to_json (nlohmann::json &j, const ObjectDictionaryValue &entry)
 
void to_json (nlohmann::json &j, const ObjectDictionaryValues &values)
 
std::expected< ObjectDictionaryValues, std::string > decodeObjectDictionaryValues (std::span< const uint8_t > data, const std::vector< DeviceParameter > &definitions)
 Splits what OS command 21 sent into one value per entry of definitions.
 
void to_json (nlohmann::json &j, const BrakeState &state)
 
std::vector< DeviceFileparseDeviceFileList (std::string_view text)
 Parses the body of a fs-getlist read into one entry per line.
 
void to_json (nlohmann::json &j, const DeviceFile &file)
 
std::vector< std::string_view > hrdColumns (somanet::HrdData data)
 The column names of one decoded sample of data, in the order a row carries them.
 
void to_json (nlohmann::json &j, const HrdRecording &recording)
 
std::string toCsv (const HrdRecording &recording)
 Renders a recording as CSV: one header row of column names, then one row per sample.
 
HrdSamples decodeHrdSamples (std::span< const uint8_t > bytes, somanet::HrdData data)
 Decodes the concatenated contents of a recording's files into samples.
 
std::expected< void, std::string > removeDeviceFile (Device &device, const std::string &filename)
 Deletes a file from a SOMANET drive's flash (FoE read of "fs-remove=<filename>").
 
void to_json (nlohmann::json &j, const EncoderRegisterResult &result)
 
void to_json (nlohmann::json &j, const OpenPhaseResult &result)
 
void to_json (nlohmann::json &j, const MotorPhaseOrderResult &result)
 
void to_json (nlohmann::json &j, const CommutationOffsetResult &result)
 
void to_json (nlohmann::json &j, const PolePairResult &result)
 
void to_json (nlohmann::json &j, const PhaseResistanceResult &result)
 
void to_json (nlohmann::json &j, const PhaseInductanceResult &result)
 
void to_json (nlohmann::json &j, const TorqueConstantResult &result)
 
void to_json (nlohmann::json &j, const SkippedCyclesResult &result)
 
void to_json (nlohmann::json &j, const TriggerErrorResult &result)
 
void to_json (nlohmann::json &j, const KueblerRegisterResult &result)
 
void to_json (nlohmann::json &j, const FirmwareLatencyResult &result)
 
std::expected< SomanetDrive, std::string > createSomanetDrive (Device &device)
 Validates that device is a SOMANET drive, then binds a view to it.
 
constexpr std::string_view toString (FsBufferTransfer transfer)
 Name of an fs-buffer direction, as a request and a response spell it.
 
std::expected< OsCommandRequest, std::string > parseOsCommandRequest (const nlohmann::json &body)
 Parses and validates a client's OS command request body.
 
std::vector< ProcedureParameterosCommandParameters ()
 What the OS command procedure accepts, as its descriptor advertises it.
 
void to_json (nlohmann::json &j, const OsCommandResult &result)
 
std::vector< ProgressSteposCommandSteps ()
 The OS command procedure's step template — one step, all idle.
 
std::expected< void, std::string > runOsCommandProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const OsCommandRequest &request)
 Runs one raw OS command as a procedure body.
 
std::expected< EncoderRegisterRequest, std::string > parseEncoderRegisterRequest (const nlohmann::json &body)
 Parses and validates a client's encoder register request body.
 
std::vector< ProcedureParameterencoderRegisterParameters ()
 What encoder register communication accepts, as its descriptor advertises it.
 
std::vector< ProgressStepencoderRegisterSteps ()
 Encoder register communication's step template — one step, idle.
 
std::expected< void, std::string > runEncoderRegisterProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const EncoderRegisterRequest &request)
 Runs one encoder register access as a procedure body.
 
std::expected< IcMuCalibrationModeRequest, std::string > parseIcMuCalibrationModeRequest (const nlohmann::json &body)
 Parses and validates a client's iC-MU calibration mode request body.
 
std::vector< ProcedureParametericMuCalibrationModeParameters ()
 What setting an iC-MU calibration mode accepts, as its descriptor advertises it.
 
std::vector< ProgressStepicMuCalibrationModeSteps ()
 The iC-MU calibration mode procedure's step template — one step, idle.
 
std::expected< void, std::string > runIcMuCalibrationModeProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const IcMuCalibrationModeRequest &request)
 Sets an iC-MU encoder's calibration mode as a procedure body.
 
std::expected< HrdStreamingRequest, std::string > parseHrdStreamingRequest (const nlohmann::json &body)
 Parses and validates a client's HRD streaming request body.
 
std::vector< ProcedureParameterhrdStreamingParameters ()
 What HRD streaming accepts, as its descriptor advertises it.
 
std::vector< ProgressStephrdStreamingSteps ()
 The HRD streaming procedure's step template — configure, then record.
 
std::expected< void, std::string > runHrdStreamingProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const HrdStreamingRequest &request)
 Records one high resolution data stream as a procedure body.
 
std::vector< ProgressStepopenPhaseDetectionSteps ()
 Open phase detection's step template — prepare, check, restore, all idle.
 
std::expected< void, std::string > runOpenPhaseDetectionProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs open phase detection as a procedure body.
 
std::vector< ProgressSteppolePairDetectionSteps ()
 Pole pair detection's step template — prepare, release the brake, detect, restore.
 
std::expected< void, std::string > runPolePairDetectionProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs pole pair detection as a procedure body.
 
std::vector< ProgressStepmotorPhaseOrderDetectionSteps ()
 Motor phase order detection's step template — prepare, release the brake, detect, restore.
 
std::expected< void, std::string > runMotorPhaseOrderDetectionProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs motor phase order detection as a procedure body.
 
std::vector< ProgressStepoffsetDetectionSteps ()
 The commissioning sequence's step template — every command in the order it runs, plus the shared prepare, brake and restore steps.
 
std::expected< void, std::string > runOffsetDetectionProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs the whole commissioning sequence as one procedure body.
 
std::vector< ProgressStepcommutationOffsetMeasurementSteps ()
 Commutation offset measurement's step template — prepare, release the brake, measure, restore.
 
std::expected< void, std::string > runCommutationOffsetMeasurementProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs commutation offset measurement as a procedure body — OS command 5 and nothing else.
 
std::vector< ProgressStepphaseResistanceMeasurementSteps ()
 Phase resistance measurement's step template — prepare, measure, restore, all idle.
 
std::expected< void, std::string > runPhaseResistanceMeasurementProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs phase resistance measurement as a procedure body.
 
std::vector< ProgressStepphaseInductanceMeasurementSteps ()
 Phase inductance measurement's step template — prepare, measure, restore, all idle.
 
std::expected< void, std::string > runPhaseInductanceMeasurementProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs phase inductance measurement as a procedure body.
 
std::expected< KueblerRegisterRequest, std::string > parseKueblerRegisterRequest (const nlohmann::json &body)
 Parses and validates a client's Kübler register request body.
 
std::vector< ProcedureParameterkueblerRegisterParameters ()
 What a Kübler register access accepts, as its descriptor advertises it.
 
std::vector< ProgressStepkueblerRegisterSteps ()
 The Kübler register procedure's step template — one step, idle.
 
std::expected< void, std::string > runKueblerRegisterProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const KueblerRegisterRequest &request)
 Reads or writes one Integro internal-encoder register as a procedure body.
 
std::expected< VelocitySourceRequest, std::string > parseVelocitySourceRequest (const nlohmann::json &body)
 Parses and validates a client's velocity source request body.
 
std::vector< ProcedureParametervelocitySourceParameters ()
 What choosing the velocity source accepts, as its descriptor advertises it.
 
std::vector< ProgressStepvelocitySourceSteps ()
 The velocity-source procedure's step template — one step, idle.
 
std::expected< void, std::string > runVelocitySourceProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const VelocitySourceRequest &request)
 Chooses the velocity loop's feedback source as a procedure body.
 
std::optional< FirmwareLatencyActionparseFirmwareLatencyAction (std::string_view token)
 Parses a firmware latency action token. std::nullopt if it names none of them.
 
std::expected< FirmwareLatencyRequest, std::string > parseFirmwareLatencyRequest (const nlohmann::json &body)
 Parses and validates a client's firmware latency request body.
 
std::vector< ProcedureParameterfirmwareLatencyParameters ()
 What measuring a firmware latency accepts, as its descriptor advertises it.
 
std::vector< ProgressStepfirmwareLatencySteps ()
 The firmware latency procedure's step template — start, observe, read, stop.
 
std::expected< void, std::string > runFirmwareLatencyProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const FirmwareLatencyRequest &request)
 Measures one internal firmware latency as a procedure body.
 
std::expected< TriggerErrorRequest, std::string > parseTriggerErrorRequest (const nlohmann::json &body)
 Parses and validates a client's trigger-error request body.
 
std::vector< ProcedureParametertriggerErrorParameters ()
 What provoking a firmware error accepts, as its descriptor advertises it.
 
std::vector< ProgressSteptriggerErrorSteps ()
 The trigger-error procedure's step template — one step, idle.
 
std::expected< void, std::string > runTriggerErrorProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const TriggerErrorRequest &request)
 Provokes a firmware error in a control service as a procedure body.
 
std::expected< SystemIdentificationRequest, std::string > parseSystemIdentificationRequest (const nlohmann::json &body)
 Parses and validates a client's system identification request body.
 
std::vector< ProcedureParametersystemIdentificationParameters ()
 What system identification accepts, as its descriptor advertises it.
 
std::vector< ProgressStepsystemIdentificationSteps ()
 The system identification procedure's step template — configure, then arm.
 
std::expected< void, std::string > runSystemIdentificationProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const SystemIdentificationRequest &request)
 Configures and optionally arms a system identification run as a procedure body.
 
std::expected< IgnoreBissStatusBitsRequest, std::string > parseIgnoreBissStatusBitsRequest (const nlohmann::json &body)
 Parses and validates a client's ignore-BiSS-status-bits request body.
 
std::vector< ProcedureParameterignoreBissStatusBitsParameters ()
 What ignoring BiSS status bits accepts, as its descriptor advertises it.
 
std::vector< ProgressStepignoreBissStatusBitsSteps ()
 The ignore-BiSS-status-bits procedure's step template — one step, idle.
 
std::expected< void, std::string > runIgnoreBissStatusBitsProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const IgnoreBissStatusBitsRequest &request)
 Starts or stops ignoring a BiSS encoder's status bits as a procedure body.
 
std::expected< SkippedCyclesRequest, std::string > parseSkippedCyclesRequest (const nlohmann::json &body)
 Parses and validates a client's skipped cycles request body.
 
std::vector< ProcedureParameterskippedCyclesParameters ()
 What reading a skipped cycles counter accepts, as its descriptor advertises it.
 
std::vector< ProgressStepskippedCyclesSteps ()
 The skipped cycles procedure's step template — one step, idle.
 
std::expected< void, std::string > runSkippedCyclesProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop, const SkippedCyclesRequest &request)
 Reads one control loop's skipped-cycle counter as a procedure body.
 
std::vector< ProgressStepreadObjectDictionarySteps ()
 The read-object-dictionary procedure's step template — one step, idle.
 
std::expected< void, std::string > runReadObjectDictionaryProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Reads every object dictionary value in one transfer, as a procedure body.
 
std::vector< ProgressSteptorqueConstantMeasurementSteps ()
 Torque constant measurement's step template — prepare, release the brake, measure, restore.
 
std::expected< void, std::string > runTorqueConstantMeasurementProcedure (Device &device, ProgressReporter &reporter, std::stop_token stop)
 Runs torque constant measurement as a procedure body.
 
std::filesystem::path firmwareCacheDir ()
 Where installed packages are kept: a firmwares subdirectory of the per-user cache.
 
std::vector< ProcedureParameterfirmwareInstallationParameters ()
 What the procedure accepts, as its descriptor advertises it.
 
std::vector< ProgressStepfirmwareInstallationSteps ()
 The procedure's step template, in order.
 
std::expected< FirmwareInstallationRequest, std::string > parseFirmwareInstallationRequest (const nlohmann::json &body)
 Parses and validates a client's installation request.
 
std::expected< void, std::string > runFirmwareInstallationProcedure (DeviceManager &deviceManager, uint16_t devicePosition, ProgressReporter &reporter, std::stop_token stop, const FirmwareInstallationRequest &request)
 Installs request's package on the device at devicePosition.
 
constexpr std::string_view toString (FirmwareLatencyAction action)
 Name of a firmware latency action (for JSON). Never returns nullptr.
 
constexpr std::string_view toString (SomanetProduct product)
 Human-readable name of a known SOMANET product (for logging / JSON). Returns "Unknown" for a product code not in SomanetProduct.
 
constexpr std::string_view somanetProductName (uint32_t productCode)
 Product name for a raw product code (object 0x1018:02), or empty if the code is not a recognised SOMANET product.
 
void to_json (nlohmann::json &j, const FullFirmwareDescriptors &descriptors)
 Serialises the descriptors and a verdict.
 
void to_json (nlohmann::json &j, const FirmwareCompatibility &compatibility)
 
void to_json (nlohmann::json &j, const HardwareComponent &component)
 Serialises a component, a product and a whole description.
 
void to_json (nlohmann::json &j, const HardwareProduct &product)
 
void to_json (nlohmann::json &j, const HardwareDescription &description)
 

Variables

constexpr std::array< std::string_view, 2 > kDefaultSkippedFirmwareFiles
 The entries an install skips unless the request names a different set.
 
constexpr uint16_t kMaxVariantOptions = 32
 The most options a file may carry (firmware MAX_VARIANTS_COUNT).
 
constexpr std::string_view kNotificationTopic = "notifications"
 The one topic every notification is published to.
 
constexpr std::array< char, 4 > kDumpMagic = {'M', 'M', 'P', 'D'}
 Magic at the very start of every dump file.
 
constexpr uint16_t kDumpFormatVersion = 1
 Current dump format version. A reader rejects an unknown major shape; bump on layout changes so old files stay identifiable.
 
constexpr std::streamoff kDumpRowCountOffset = 16
 Byte offset of the rowCount field within the fixed prefix. The writer streams rows first, then seeks here to patch the final count — so the stream must be seekable.
 
constexpr std::string_view kStoreParametersProcedure = "store-parameters"
 Procedure name for storing parameters, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kStoreParametersStep = "store"
 The single step storing parameters reports against.
 
constexpr std::string_view kRestoreDefaultParametersProcedure = "restore-default-parameters"
 Procedure name for restoring default parameters, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kRestoreDefaultParametersStep = "restore"
 The single step restoring default parameters reports against.
 
constexpr size_t kFirmwareServiceByte = 1
 
constexpr size_t kBissIgnoreByte = 1
 
constexpr unsigned kBissIgnoreEncoderShift = 1
 
constexpr uint8_t kBissIgnoreTrigger = 0x01
 
constexpr size_t kKueblerDirectionByte = 1
 
constexpr size_t kKueblerAddressByte = 2
 
constexpr size_t kKueblerLengthByte = 3
 
constexpr size_t kKueblerValueLsbByte = 4
 
constexpr size_t kVelocitySourceByte = 1
 
constexpr size_t kFirmwareLatencyActionByte = 1
 
constexpr size_t kFirmwareLatencyIndexByte = 2
 
constexpr size_t kFirmwareLatencyMaximumOffset = 0
 
constexpr size_t kFirmwareLatencyConfiguredOffset = 3
 
constexpr size_t kFirmwareLatencyValueBytes = 3
 
constexpr uint8_t kStartLatencyMeasurement = 0
 
constexpr uint8_t kGetAndClearMaximumLatency = 1
 
constexpr uint8_t kStopLatencyMeasurements = 2
 
constexpr uint32_t kLatencyTickNanoseconds = 10
 
constexpr size_t kTriggerErrorServiceByte = 1
 
constexpr size_t kTriggerErrorTypeByte = 2
 
constexpr size_t kSystemIdParameterByte = 1
 
constexpr size_t kSystemIdValueMsbByte = 2
 
constexpr size_t kOsCommandSize = 8
 Byte length of the OS command and response octet strings (0x1023:01 / 0x1023:03). Manufacturer-specific — the firmware specification allows it to grow, so read it from here rather than writing 8 at a call site.
 
constexpr std::string_view kFsBufferFilename = "fs-buffer"
 The FoE filename that moves bulk data for an OS command.
 
constexpr std::array< uint32_t, 1 > kObjectsOutsideOdValues
 The entries a SOMANET drive answers for over CoE that OS command 21 does not carry.
 
constexpr std::string_view kOsCommandProcedure = "os-command"
 Procedure name for the raw OS command, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kOsCommandStep = "command"
 The single step the OS command procedure reports against.
 
constexpr std::string_view kEncoderRegisterProcedure = "encoder-register-communication"
 Procedure name for encoder register communication, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kEncoderRegisterStep = "register-access"
 The single step encoder register communication reports against.
 
constexpr std::string_view kIcMuCalibrationModeProcedure = "ic-mu-calibration-mode"
 Procedure name for setting an iC-MU calibration mode, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kIcMuCalibrationModeStep = "set-mode"
 The single step setting an iC-MU calibration mode reports against.
 
constexpr std::string_view kHrdStreamingProcedure = "hrd-streaming"
 Procedure name for recording a high resolution data stream, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kHrdConfigureStep = "configure-stream"
 The step that arms the recording — chooses the signal and the duration, and clears the files the last recording left behind.
 
constexpr std::string_view kHrdRecordStep = "record"
 The step that records. Occupies the whole configured duration.
 
constexpr std::string_view kKueblerRegisterProcedure = "kuebler-register-communication"
 Procedure name for a Kübler encoder register access, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kKueblerRegisterStep = "register-access"
 The single step a Kübler register access reports against.
 
constexpr std::string_view kVelocitySourceProcedure = "velocity-source"
 Procedure name for choosing the velocity feedback source, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kVelocitySourceStep = "set-source"
 The single step choosing the velocity source reports against.
 
constexpr std::string_view kFirmwareLatencyProcedure = "firmware-latency-measurement"
 Procedure name for measuring a firmware latency, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kFirmwareLatencyStartStep = "start-measurement"
 The step that starts a measurement, and clears whatever the latency recorded.
 
constexpr std::string_view kFirmwareLatencyObserveStep = "observe"
 The step that lets the drive run while the measurement collects. Occupies the whole requested duration, and only FirmwareLatencyAction::kMeasure performs it.
 
constexpr std::string_view kFirmwareLatencyReadStep = "read-maximum"
 The step that reads and clears the recorded maximum.
 
constexpr std::string_view kFirmwareLatencyStopStep = "stop-measurements"
 The step that stops both measurements.
 
constexpr std::string_view kTriggerErrorProcedure = "trigger-error"
 Procedure name for provoking a firmware error, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kTriggerErrorStep = "trigger"
 The single step provoking a firmware error reports against.
 
constexpr std::string_view kSystemIdentificationProcedure = "system-identification"
 Procedure name for configuring a system identification run, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kSystemIdConfigureStep = "configure-chirp"
 The step that writes the chirp's five settings.
 
constexpr std::string_view kSystemIdArmStep = "arm"
 The step that arms the run — or disarms it.
 
constexpr std::string_view kIgnoreBissStatusBitsProcedure = "ignore-biss-status-bits"
 Procedure name for ignoring a BiSS encoder's status bits, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kIgnoreBissStatusBitsStep = "set-ignore"
 The single step ignoring BiSS status bits reports against.
 
constexpr std::string_view kSkippedCyclesProcedure = "skipped-cycles-counter"
 Procedure name for reading a skipped cycles counter, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kSkippedCyclesStep = "read-counter"
 The single step reading a skipped cycles counter reports against.
 
constexpr std::string_view kReadObjectDictionaryProcedure = "read-object-dictionary"
 Procedure name for reading the whole object dictionary, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kReadObjectDictionaryStep = "read-dictionary"
 The single step reading the whole object dictionary reports against.
 
constexpr std::string_view kPrepareStep = "prepare"
 The step ids shared by every procedure that prepares a drive, measures, and puts it back.
 
constexpr std::string_view kReleaseBrakeStep = "release-brake"
 
constexpr std::string_view kRestoreStep = "restore"
 
constexpr std::string_view kOpenPhaseDetectionProcedure = "open-phase-detection"
 Procedure name for open phase detection, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kOpenPhaseDetectionStep = "open-phase-detection"
 The step open phase detection's own measurement reports against.
 
constexpr std::string_view kPolePairDetectionProcedure = "pole-pair-detection"
 Procedure name for pole pair detection, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kPolePairDetectionStep = "pole-pair-detection"
 The step pole pair detection's own measurement reports against.
 
constexpr std::string_view kMotorPhaseOrderDetectionProcedure
 Procedure name for motor phase order detection, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kMotorPhaseOrderDetectionStep = "motor-phase-order-detection"
 The step motor phase order detection's own measurement reports against.
 
constexpr std::string_view kOffsetDetectionProcedure = "offset-detection"
 Procedure name for the whole commissioning sequence, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kCommutationOffsetMeasurementProcedure
 Procedure name for commutation offset measurement, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kCommutationOffsetMeasurementStep
 The step commutation offset measurement's own measurement reports against.
 
constexpr std::string_view kSetBrakeStep = "set-brake"
 The step that puts the brake where the configured method needs it.
 
constexpr std::string_view kPhaseResistanceMeasurementProcedure
 Procedure name for phase resistance measurement, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kPhaseResistanceMeasurementStep = "phase-resistance-measurement"
 The step phase resistance measurement's own measurement reports against.
 
constexpr std::string_view kPhaseInductanceMeasurementProcedure
 Procedure name for phase inductance measurement, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kPhaseInductanceMeasurementStep = "phase-inductance-measurement"
 The step phase inductance measurement's own measurement reports against.
 
constexpr std::string_view kTorqueConstantMeasurementProcedure
 Procedure name for torque constant measurement, as it appears in its URL and its snapshot key.
 
constexpr std::string_view kTorqueConstantMeasurementStep = "torque-constant-measurement"
 The step torque constant measurement's own measurement reports against.
 
constexpr std::string_view kFirmwareInstallationProcedure = "firmware-installation"
 Procedure name, as it appears in its URL and its snapshot key.
 
constexpr uint32_t kSynapticonVendorId = 0x000022D2
 Synapticon's EtherCAT Vendor ID (object 0x1018:01) — the discriminator for a SOMANET drive and the single source of truth for the vendor check.
 

Typedef Documentation

◆ DeviceParameterValue

using mm::node::DeviceParameterValue = typedef std::variant<int8_t, int16_t, int32_t, int64_t, uint8_t, uint16_t, uint32_t, uint64_t, float, double, std::string, std::vector<uint8_t> >

Decoded value of a single device parameter (CoE object dictionary entry).

The variant alternatives cover the standard ETG.1020 data types that can be transferred via SDO upload. Use std::visit to dispatch on the active type.

◆ DumpRecordReader

using mm::node::DumpRecordReader = typedef std::function<bool(uint64_t seq, ProcessDataRing::Record& out)>

Reads the record for seq into out; returns false if it is no longer available (lapped or a torn read). Wraps ProcessDataRing::readRecord.

◆ HrdSamples

using mm::node::HrdSamples = typedef std::variant<std::vector<HrdEncoderSample>, std::vector<HrdSystemIdentificationSample> >

A decoded recording's samples: exactly one vector, whichever the data selection implies.

A variant rather than two vectors with one left empty, so a recording cannot claim to be encoder data while carrying velocity samples.

◆ ProcedureBody

using mm::node::ProcedureBody = typedef std::function<std::expected<void, std::string>( const ProcedureContext&, ProgressReporter&, std::stop_token)>

A procedure's work: everything one run does, as a plain callable.

It receives the context above, the reporter to record progress on, and the stop token to check between steps. It takes a Device& rather than a profile view so that ProcedureManager stays as profile-ignorant as DeviceManager — a body that needs a SomanetDrive binds one itself, and the manager never names a profile type.

Returning an error fails the run. A body should normally fail the step that went wrong (via the reporter) as well, so the snapshot says where it stopped; the returned string is what a caller sees when the failure happened outside any step.

There is one body shape, and no lock behind it. A body may call anything, including DeviceManager::scan and transitionToState, because holding a device no longer holds a lock.

Enumeration Type Documentation

◆ Cia402Command

enum class mm::node::Cia402Command
strong

High-level state-machine actions a client can command (the named transitions a UI exposes as buttons). Distinct from cia402::Command (raw controlword bit patterns).

Enumerator
kEnable 
kDisable 
kQuickStop 
kFaultReset 

◆ Cia402TargetKind

enum class mm::node::Cia402TargetKind
strong

Which cyclic setpoint a target write addresses. Exactly one is active at a time — the one matching the drive's operation mode (position for PP/CSP, velocity for PV/CSV, torque for PT/CST) — so a target write names its kind rather than setting all three.

Enumerator
kPosition 
kVelocity 
kTorque 

◆ CompleteAccessSupport

enum class mm::node::CompleteAccessSupport : uint8_t
strong

Runtime discovery state of CoE Complete Access support. CA is optional in CoE and the EEPROM capability hint is unreliable (SOMANET advertises completeAccess=false while CA in fact works), so support is probed: the first grouped read attempts CA and the outcome is remembered — the runtime probe, not the hint, is authoritative.

Enumerator
kUnknown 
kSupported 
kUnsupported 

◆ DeclaredSubindexReads

enum class mm::node::DeclaredSubindexReads : uint8_t
strong

Whether a device serves the subindices an array or a record declares but does not hold.

The two answers are both legitimate, and they cost the master very different amounts. An array or a record states in its subindex 0 how many entries are in use, and the enumeration deliberately lists the rest so a free PDO mapping slot appears like any other entry. Reading one of their values is a different request. CiA 301 says it is refused. Some devices answer anyway, and reading a SOMANET Node's free slots costs under a millisecond each.

A device that refuses is the expensive case, because SOMANET firmware refuses by silence rather than by abort, at a full 700 ms mailbox timeout each. So this is discovered once and remembered: the first such read that fails marks the device, and later objects stop at their count instead of paying the timeout again. A device that answers is never marked and keeps every value.

Learned rather than assumed, because assuming the refusal throws away values a well-behaved device would have given. kUnknown is the state in which every declared subindex is attempted.

One timeout per device, not per entry. On a SOMANET Integro the first sweep spends 700 ms on 0x1600:08 and every later object stops at its count without a transfer, so 53 timeouts become one: 36 s becomes 2.8 s, and 2.2 s once the state is set.

Nothing here names a product or a firmware version. The state keys on a read that failed, so a device that answers is never affected, and a device that aborts properly gets the same skipping at a fraction of the cost. If the silence is ever fixed this can be deleted for about 0.3 s.

Enumerator
kUnknown 
kServed 
kRefused 

◆ FirmwareLatencyAction

enum class mm::node::FirmwareLatencyAction : uint8_t
strong

What one firmware latency run should do.

Three of these are the firmware's own actions and the fourth is this master's. OS command 22 starts a measurement, reads its maximum, or stops measuring — a worthwhile figure therefore takes two commands with the drive running in between, which is a workflow rather than a command. kMeasure is that workflow performed as one run; the other three are the raw actions, kept because a measurement worth having may need to span a whole production cycle rather than the seconds a single procedure run can wait.

Enumerator
kMeasure 

Start, let the drive run for the requested duration, then read and clear the maximum. The one action that answers with a number.

kStart 

Start measuring and leave it running, to be read by a later run.

kReadMaximum 

Read and clear the maximum of a measurement already running (or already stopped).

kStop 

Stop measuring — necessarily both latencies, as the command has no per-latency stop.

◆ FirmwareMatch

enum class mm::node::FirmwareMatch
strong

Which of a device's descriptors a package matched.

Enumerator
kNone 

Neither — the package is for other hardware.

kAssembly 

The assembly descriptor: firmware customised for the assembled product.

kDevice 

The device descriptor: the generic build for the hardware itself.

◆ FsBufferTransfer

enum class mm::node::FsBufferTransfer : uint8_t
strong

Which way an OS command's fs-buffer transfer moves bytes.

Enumerator
kNone 

The command uses no fs-buffer. The default.

kRead 

Read what the command writes (an FoE read of kFsBufferFilename).

kWrite 

Send the command what it needs (an FoE write of kFsBufferFilename).

◆ GenericObject

enum mm::node::GenericObject : uint16_t

Generic CANopen device-profile (CiA301) object indices — present on any CoE device, independent of the CiA402 drive profile. Simple VAR objects are addressed at subindex 0; RECORD objects (0x1010, 0x1011, 0x1016, 0x1018, 0x1023) at their documented sub-entries.

Enumerator
kDeviceType 

UNSIGNED32, ro — mandatory; the device profile it speaks.

kErrorRegister 

UNSIGNED8, ro (volatile) — active error class bit field.

kCobIdSync 

INTEGER32, rw — COB-ID of the SYNC message.

kCommunicationCyclePeriod 

INTEGER32, rw — communication cycle period in µs.

kManufacturerDeviceName 

VISIBLE_STRING, ro — human-readable device name.

kManufacturerSoftwareVersion 

VISIBLE_STRING, ro — firmware/software version.

kGuardTime 

UNSIGNED16, rw — node guarding guard time in ms.

kLifeTimeFactor 

UNSIGNED8, rw — node guarding life time factor.

kStoreParameters 

RECORD, rw — save parameters to non-volatile storage.

kRestoreDefaultParameters 

RECORD, rw — restore default parameters.

kConsumerHeartbeatTime 

RECORD, rw — consumer heartbeat time in ms.

kProducerHeartbeatTime 

UNSIGNED16, rw — producer heartbeat time in ms.

kIdentity 

IDENTITY record, ro — vendor/product/revision/serial.

kSynchronousCounterOverflowValue 

UNSIGNED8, rw — SYNC counter overflow value.

kOsCommand 

RECORD — command (rw) / status + response (ro, volatile).

kOsCommandMode 

UNSIGNED8, wo — write-only, not readable; setter only.

◆ OperationModeKind

enum class mm::node::OperationModeKind : uint8_t
strong

Where a mode is defined, which is also how much can be said about it.

Enumerator
kStandard 

Defined by CiA402; its support is advertised by a bit of 0x6502.

kManufacturer 

Defined by the vendor; 0x6502 has no bit this code can read for it.

◆ OsCommandError

enum class mm::node::OsCommandError : uint8_t
strong

The general OS error codes — the ones any command can report, counting down from 254. Command-specific codes count up from 0 and are named by the command that issued them, not here (open phase detection's 0 is "open terminal A", phase resistance's 0 is "current amplitude error", ...).

Enumerator
kNotAllowed 

Preconditions not met (wrong mode of operation, say).

kAborted 

The abort the master requested via 0x1024 was carried out.

kTimeout 

No downstream service acknowledged the command (or the abort) within the drive's own reception timeout — 20000 drive-control cycles, so about 20 seconds at a 1 ms loop, and it scales with that loop's period. Measured at 20.04 s on a SOMANET Integro with the master waiting 60 s. It means "no service recognised this", not "the drive was slow", so it is also what a command addressed at a service the firmware does not run comes back as.

kUnsupported 

The command ID does not exist on this drive.

kReserved 

Reserved for future expansion of the feature.

◆ OsCommandStatus

enum class mm::node::OsCommandStatus : uint8_t
strong

Terminal OS command status — byte 0 of the response (0x1023:03), which the firmware mirrors from 0x1023:02. Only these four values end a command; 100-200 (executing, with percentage) and 255 (executing) are transient and never surface to a caller.

Enumerator
kCompleted 

Completed, no error, no response data.

kCompletedWithData 

Completed, no error, response data available.

kFailed 

Completed with error, no response data.

kFailedWithData 

Completed with error, OS error code and response data available.

◆ ParameterOrigin

enum class mm::node::ParameterOrigin : uint8_t
strong

Where a parameter's definition (schema/metadata) came from.

A CoE slave enumerates its object dictionary over SDO-Info (ObjectDictionary). A mailbox-less slave (an EtherCAT coupler / simple I/O terminal) has no object dictionary; its process-data objects are instead described by its SII EEPROM (Sii), which supplies index/subindex/data type and bit length but carries no live SDO access — such a parameter's value is only ever the process-image value, never an SDO upload.

Enumerator
ObjectDictionary 

Enumerated over the CoE object dictionary (SDO-Info).

Sii 

Derived from the SII EEPROM PDO categories (no CoE mailbox).

◆ ParameterType

enum class mm::node::ParameterType : uint8_t
strong

What kind of value a procedure parameter takes — the client's cue for which control to render, and the only vocabulary a generic form has to understand.

Deliberately a short closed list rather than a JSON Schema fragment: a client renders a control per kind, and every kind here is one a procedure actually asks for. A new kind is added when a procedure needs it, which keeps the renderer as small as the set of things procedures take.

Enumerator
kInteger 

A whole number, bounded by minValue / maxValue.

kBoolean 

A checkbox.

kEnum 

One of options — a value the client picks rather than types.

kByteArray 

Exactly length byte values (the raw OS command's request bytes).

kString 

Free text — a filename, a label.

kStringArray 

A list of free-text values the user edits as a list.

kFile 

A file's contents, base64-encoded; a client renders a file picker.

◆ ProcedureStatus

enum class mm::node::ProcedureStatus : uint8_t
strong

Overall status of a procedure run — the single field a polling client checks.

The step statuses plus kCancelled, which exists because folding a user cancel into kFailed would lose the difference between "the drive could not do it" and "I stopped it" — exactly the distinction someone returning to a page needs. A polling loop is while(status == kRunning).

Enumerator
kIdle 

Never run on this device (or cleared by a rescan).

kRunning 

A run is in progress.

kSucceeded 

The last run completed successfully.

kFailed 

The last run failed; the failing step carries the reason.

kCancelled 

The last run was stopped by the user before it finished.

◆ ProgressStatus

enum class mm::node::ProgressStatus : uint8_t
strong

Status of one step within a procedure.

A step never reports cancellation: cancelling stops the procedure, leaving whichever step was running as kRunning and the ones after it kIdle, which is a truthful record of how far it got. The cancellation itself is reported by ProcedureStatus.

Enumerator
kIdle 

Not started (the initial state of every step in a template).

kRunning 

Started and not yet finished.

kSucceeded 

Finished; ProgressStep::value carries its measurement, if it has one.

kFailed 

Finished badly; ProgressStep::error says why.

◆ RestoreGroup

enum class mm::node::RestoreGroup : uint8_t
strong

Which group of default parameters to restore (which 0x1011 sub-entry to command). The enum value is the sub-entry number, so it maps straight to the object subindex.

Enumerator
kAll 

0x1011:01 — all default parameters.

kCommunication 

0x1011:02 — communication default parameters.

kApplication 

0x1011:03 — application default parameters.

kManufacturer 

0x1011:04 — manufacturer-defined default parameters.

◆ SomanetProduct

enum class mm::node::SomanetProduct : uint32_t
strong

Known SOMANET product codes (object 0x1018:02) under kSynapticonVendorId.

The product code together with the revision number keys the object-dictionary cache (ParameterCache). This enumerates the products we recognise; a device may report a code not listed here (a newer or unreleased product) — that is not an error, it simply has no name.

Enumerator
kNode 

SOMANET Node.

kCirculo 

SOMANET Circulo.

kCirculoSmm 

SOMANET Circulo SMM.

kIntegro 

SOMANET Integro.

◆ SyncState

enum class mm::node::SyncState : uint8_t
strong

Tracks how a cached parameter value relates to the device.

A device may be edited while offline (powered off, or in INIT with no mailbox); this flag lets callers tell a freshly-read value from a stale or pending one (see NEXTGEN.md — "tag offline values with a freshness flag").

Enumerator
Unknown 

Never read; value is the type-appropriate default.

Synced 

value matches the device (last successful read or write).

Pending 

value was set locally while offline / after a failed write.

◆ VariantOperationMode

enum class mm::node::VariantOperationMode : uint16_t
strong

How the drive treats its variant options (firmware OPTIONS_MODE_*).

kPassive is the failure state as much as a mode: firmware falls back to it when the file is missing, its signature does not verify, or its chip id belongs to another device — so a drive reporting passive is one whose licensing did not take.

Enumerator
kPassive 
kTrial 
kProduction 
kLive 

Function Documentation

◆ booleanParameter()

ProcedureParameter mm::node::booleanParameter ( std::string  name,
std::string  title,
std::string  description,
nlohmann::json  defaultValue 
)

A true/false parameter. defaultValue as in integerParameter.

◆ brakeState()

std::expected< BrakeState, std::string > mm::node::brakeState ( DeviceManager deviceManager,
uint16_t  slavePosition 
)

Reads a drive's brake configuration and current state (0x2004).

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
Returns
The brake state, or an error if the device is unknown, is not a SOMANET drive, or a read fails.

◆ buildEniResponse()

std::expected< nlohmann::json, std::string > mm::node::buildEniResponse ( std::string_view  xml)

Reads an ENI document and renders it as JSON, with each datagram explained.

The document alone is not a view. An ENI is a script of EtherCAT datagrams, so a page that only listed them would show a reader FPWR to 2064, data 0018060064000100 and leave the work undone. This names the register that address selects and decodes the payload where the payload is a register block, so the same command reads as sync manager 2: start 0x1800, length 6, enabled.

The decode lives here rather than in a client, because it is the same ESC knowledge mm::comm already holds and mm::node::collectEni already uses to build these commands. A second decoder in TypeScript would drift against the encoder it is supposed to mirror.

Offline, like the ESI and SII parsers this sits beside. No bus is touched and none is needed — the point is reading a document somebody else's configuration tool wrote.

The result carries the network under "network", the reader's warnings under "warnings", and a count of devices and commands under "summary".

Parameters
xmlThe complete ENI document.
Returns
The rendered JSON, or an error when the document will not read.

◆ buildProcessImage()

std::expected< ProcessImage, std::string > mm::node::buildProcessImage ( const mm::comm::PdoLayout layout,
const std::vector< Device > &  devices 
)

Assembles a ProcessImage from the driver layout and per-device PDO mappings.

Matches each device to its window in layout by bus position and combines the window offset with the device's per-object bit offsets to produce absolute positions. Padding entries (index == 0) are dropped — they bind to no object. Devices must have had Device::readFlatPdoMapping called already.

Parameters
layoutPer-slave windows and image sizes from FieldbusDriver::processDataLayout.
devicesDevices whose flatPdoMapping() supply the per-object offsets.
Returns
The assembled image, or an error string if a device has a mapping but no matching window in layout, or its mapped width overflows the window the driver reserved.

◆ byteArrayParameter()

ProcedureParameter mm::node::byteArrayParameter ( std::string  name,
std::string  title,
std::string  description,
size_t  length 
)

A parameter taking exactly length byte values.

Always required: a default set of command bytes would be a command nobody asked to run.

◆ cancelProcedure()

std::expected< void, ProcedureError > mm::node::cancelProcedure ( DeviceManager deviceManager,
ProcedureManager procedureManager,
uint16_t  devicePosition,
std::string_view  name 
)

Asks the running name on devicePosition to stop.

Cancels the run, not the record: the retained snapshot stays behind reporting how far it got.

Returns
Void if a run was in flight and got the stop request. kUnknownProcedure covers both an unrecognised name and a recognised one with nothing running — from a client's side both mean "there is no run here to cancel".

◆ checkFirmwareCompatibility() [1/2]

FirmwareCompatibility mm::node::checkFirmwareCompatibility ( const HardwareDescription description,
const FirmwarePackageName packageName,
const IntegroVariant variant = nullptr 
)

Decides whether packageName belongs on the hardware description describes.

The whole descriptor string is compared, never its decoded parts. That is what makes the check correct for descriptors the numeric convention does not cover, and it is how the specification frames the operation: "Finding compatible firmware inside a directory with many files can be done by searching the directory for the @c fullFirmwareDescriptor string" (§3.4.2).

Returns a value rather than an expected because with both inputs already parsed there is nothing left to fail: a package that does not fit is a verdict, and the caller wants both descriptors so it can say which hardware the package was for.

Parameters
descriptionA parsed hardware description.
packageNameA parsed package filename.
variantThe device's parsed .variant, or nullptr when it has none.
Returns
The verdict.

◆ checkFirmwareCompatibility() [2/2]

std::expected< FirmwareCompatibility, std::string > mm::node::checkFirmwareCompatibility ( std::string_view  hardwareDescriptionContent,
std::string_view  packageFilename,
const IntegroVariant variant = nullptr 
)

Parses both inputs, then decides — the whole check from a file's text and a filename.

The entry point for a caller holding raw inputs (a device's file, a user's chosen filename). The failure shape differs from the overload above on purpose: inputs that cannot be read at all — a filename that is not a package name, content that is not a hardware description — are an unexpected, because there is no verdict to give and the reason is what a caller shows instead.

Parameters
hardwareDescriptionContentThe device's .hardware_description, as text.
packageFilenameBare package filename, with no directory part.
variantThe device's parsed .variant, or nullptr when it has none.
Returns
The verdict, or why no verdict could be reached.

◆ checkFirmwarePackage()

std::expected< FirmwareCompatibility, std::string > mm::node::checkFirmwarePackage ( DeviceManager deviceManager,
uint16_t  slavePosition,
std::string_view  packageFilename 
)

Reads what a device is and decides whether a firmware package belongs on it.

Thin forward to SomanetDrive::checkFirmwarePackage. Two FoE reads; an incompatible package is a verdict rather than an error, so an error here means the question could not be asked.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
packageFilenameBare package filename, with no directory part.
Returns
The verdict, or why no verdict could be reached.

◆ cia402Status()

std::expected< Cia402Status, std::string > mm::node::cia402Status ( DeviceManager deviceManager,
uint16_t  slavePosition 
)

Reads a device's CiA402 control snapshot (state, status/control words, active mode).

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
Returns
The snapshot, or an error string if the device is unknown, not a CiA402 drive, or a read fails.

◆ collectEni()

std::expected< EniCollection, std::string > mm::node::collectEni ( DeviceManager manager,
const EniCollectorOptions options 
)

Reads the live bus and builds an ENI network from it.

The document describes the bus as this master has configured it, which is why it needs the bus configured: FMMUs and logical addresses come into being at the SAFE-OP transition, and before that there is no mapping to describe. So a bus in PRE-OP is refused rather than guessed at.

This drives the bus. Each device's SII is read for its port layout and bootstrap mailbox, and its PDO assignment is read over CoE, so the call costs one SII read and a short burst of SDO uploads per device. It is an export action, not an accessor.

Distributed clocks are left out. The DC element needs an AssignActivate word, and a SOMANET drive does not carry the SII category that holds one, so it would have to come from the device's ESI. The generated configuration therefore runs in free-run, which is how Motion Master runs the bus itself.

Parameters
managerThe device manager, with a published process image.
optionsWhat the bus cannot answer for.
Returns
The collected network, or an error when the bus has no image, has no devices, or when options is incomplete.

◆ commutationOffsetMeasurementSteps()

std::vector< ProgressStep > mm::node::commutationOffsetMeasurementSteps ( )

Commutation offset measurement's step template — prepare, release the brake, measure, restore.

◆ createCia402Drive()

std::expected< Cia402Drive, std::string > mm::node::createCia402Drive ( Device device)

Validates that device implements the CiA402 profile, then binds a view to it.

The check is offline-safe: it requires the controlword (0x6040) and statusword (0x6041) objects to be present in the device's parameter map (populated by Device::initializeParameters). No bus I/O is performed.

Parameters
deviceDevice to view. The reference must outlive the returned view.
Returns
A Cia402Drive bound to device, or an error string if it is not a CiA402 drive (or its parameters are not initialised).

◆ createProfileDevice()

std::expected< ProfileDevice, std::string > mm::node::createProfileDevice ( Device device)

Binds a generic device-profile view to device.

Offline-safe discriminator: the device must expose the device type (0x1000) in its (already-enumerated) object dictionary — a mandatory CANopen object present on any CoE device, so this only guards against an un-enumerated device, not a wrong device class. No bus I/O is performed.

Parameters
deviceDevice to view. The reference must outlive the returned view.
Returns
A ProfileDevice bound to device, or an error string if its parameters have not been initialised.

◆ createSomanetDrive()

std::expected< SomanetDrive, std::string > mm::node::createSomanetDrive ( Device device)

Validates that device is a SOMANET drive, then binds a view to it.

Requires the vendor ID to be Synapticon's (kSynapticonVendorId) and the device to satisfy the CiA402 check (createCia402Drive). Both are offline-safe — vendor ID is immutable identity read at scan, the CiA402 check reads the parameter map — so no bus I/O is performed.

Parameters
deviceDevice to view. The reference must outlive the returned view.
Returns
A SomanetDrive bound to device, or an error string if it is not a SOMANET drive.

◆ decodeHrdSamples()

HrdSamples mm::node::decodeHrdSamples ( std::span< const uint8_t >  bytes,
somanet::HrdData  data 
)

Decodes the concatenated contents of a recording's files into samples.

Pure: the transform from bytes to samples, with no device involved, which is what makes the firmware's two on-disk layouts testable without one. Little-endian, unlike the OS command payloads that configure the stream — these are words the firmware wrote to a file rather than bytes it packed into a CoE object.

A trailing partial sample is ignored rather than rejected: the drive's files are fixed-size blocks, so a recording that does not fill the last one ends in padding. The caller learns how much was left over from bytes.size() % somanet::hrdSampleSize.

Parameters
bytesEvery file's contents, concatenated in file order.
dataWhich layout to read them as — the same selection the stream was configured with.
Returns
The decoded samples, in the alternative data implies.

◆ decodeObjectDictionaryValues()

std::expected< ObjectDictionaryValues, std::string > mm::node::decodeObjectDictionaryValues ( std::span< const uint8_t >  data,
const std::vector< DeviceParameter > &  definitions 
)

Splits what OS command 21 sent into one value per entry of definitions.

Walks definitions in order and takes each entry's declared width off the front of data. A scalar's width comes from its data type; a string's or a byte array's comes from its bit length, which is the only record of how much room the drive reserved for it.

Free rather than a member so it can be tested against a recorded transfer without a device, and so the widths it uses are visible in one place.

Entries named by kObjectsOutsideOdValues are left out of the walk, because the transfer does not carry them.

Parameters
dataThe bytes the drive sent.
definitionsThe device's object dictionary entries, sorted ascending by index and then subindex — what Device::parametersOrdered returns.
Returns
One value per definition the transfer carries, or a message naming the mismatch: the widths not adding up to data.size(), or an entry whose bytes could not be decoded.

◆ decodeSdoBytes()

std::expected< DeviceParameterValue, std::string > mm::node::decodeSdoBytes ( uint16_t  dataType,
std::span< const uint8_t >  bytes 
)

Decodes a raw SDO byte sequence according to an ETG.1020 data type code.

Parameters
dataTypeETG.1020 data type code (e.g. 0x0007 = UNSIGNED32).
bytesBytes returned by an SDO upload.
Returns
The decoded value on success, or an error string if dataType is unsupported or bytes is too short for the type.

◆ defaultValueForDataType()

DeviceParameterValue mm::node::defaultValueForDataType ( uint16_t  dataType)

Returns a zero-equivalent value for the given ETG.1020 dataType.

The variant alternative a value of this type is reported as, holding its type-appropriate zero. Unknown data types fall back to std::vector<uint8_t>{}.

◆ deviceNotFound()

std::unexpected< std::string > mm::node::deviceNotFound ( uint16_t  slavePosition)
inline

The error to return when a bus position resolves to no device.

One wording, so every surface answers the same way. Converts to any std::expected<T, std::string>.

◆ deviceOperationModes()

std::expected< OperationModes, std::string > mm::node::deviceOperationModes ( Device device)

Builds the operation-mode table for device.

Reads 0x6502 through a Cia402Drive view — the one bus transaction here, and a cached one — and marks each standard mode from its bit. The manufacturer half is appended only for a Synapticon device, from somanet::kOperationModes, since a vendor's modes mean nothing on another vendor's drive.

Parameters
deviceDevice to describe, borrowed for the call.
Returns
The table, or why 0x6502 could not be read.

◆ encoderRegisterParameters()

std::vector< ProcedureParameter > mm::node::encoderRegisterParameters ( )

What encoder register communication accepts, as its descriptor advertises it.

◆ encoderRegisterSteps()

std::vector< ProgressStep > mm::node::encoderRegisterSteps ( )

Encoder register communication's step template — one step, idle.

◆ encodeSdoBytes()

std::expected< std::vector< uint8_t >, std::string > mm::node::encodeSdoBytes ( uint16_t  dataType,
const DeviceParameterValue value 
)

Serialises a DeviceParameterValue to raw SDO bytes — the inverse of decodeSdoBytes.

The active variant alternative must match dataType (numeric types expect the scalar of the corresponding width; string types expect std::string). Strings are written as their raw bytes with no trailing NUL so that decodeSdoBytes(t, encodeSdoBytes(t, v)) round-trips exactly. Unknown / composite types expect a std::vector<uint8_t> and are copied verbatim.

Parameters
dataTypeETG.1020 data type code.
valueValue to serialise.
Returns
The encoded bytes on success, or an error string if value's alternative does not match dataType.

◆ engageBrake()

std::expected< BrakeState, std::string > mm::node::engageBrake ( DeviceManager deviceManager,
uint16_t  slavePosition,
std::chrono::milliseconds  settle 
)

Engages a drive's brake and waits settle for it to bite.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
settleHow long to wait after commanding the brake before returning.
Returns
The brake state read back afterwards, or why the attempt failed.

◆ enumParameter()

ProcedureParameter mm::node::enumParameter ( std::string  name,
std::string  title,
std::string  description,
nlohmann::json  defaultValue,
std::vector< ParameterOption options 
)

A parameter whose value is one of options. defaultValue as in integerParameter, and it should be one of the option values.

◆ extractBits() [1/2]

std::vector< uint8_t > mm::node::extractBits ( std::span< const uint8_t >  src,
uint32_t  bitOffset,
uint16_t  bitLength 
)

Extracts bitLength bits at bitOffset from src into a fresh LSB-aligned little-endian byte vector (ceil(bitLength/8) bytes), as the SDO encoding would.

Byte-aligned extents are a plain copy; sub-byte extents are assembled bit by bit. Allocates — use the out overload on any path that must not.

◆ extractBits() [2/2]

void mm::node::extractBits ( std::span< const uint8_t >  src,
uint32_t  bitOffset,
uint16_t  bitLength,
std::span< uint8_t >  out 
)

Extracts bitLength bits at bitOffset from src into the caller's out buffer.

The non-allocating form of extractBits, and the primitive the vector-returning overload is written over — the RT decode loop runs this once per mapped object per cycle into a stack buffer, where a heap allocation is not permitted.

out is zeroed in full before anything is written, so a buffer wider than the value (the expected case: an 8-byte scratch for a 2-byte object) is left with defined zero padding rather than the caller's stale bytes. At most ceil(bitLength/8) bytes are then written, clamped to out.size(): an out too small to hold the value is filled as far as it goes rather than overrun, matching how a src too short to supply the bits leaves the remainder zero.

Parameters
srcSource image bytes.
bitOffsetAbsolute bit offset within src.
bitLengthWidth of the value in bits.
outDestination buffer; zeroed, then filled LSB-aligned little-endian.

◆ fileParameter()

ProcedureParameter mm::node::fileParameter ( std::string  name,
std::string  title,
std::string  description,
nlohmann::json  defaultValue 
)

A parameter carrying a whole file, base64-encoded in a JSON string.

The transport is base64 because JSON has no binary type and a procedure's parameters travel in its request body. Decode with mm::core::base64Decode.

Parameters
defaultValueAs in integerParameter; a file parameter is normally required, but one that has an alternative source (a package already on the server, named by another parameter) is optional.

◆ firmwareCacheDir()

std::filesystem::path mm::node::firmwareCacheDir ( )

Where installed packages are kept: a firmwares subdirectory of the per-user cache.

That places it under the same root /api/user-cache serves, so a cached package is listable, downloadable and deletable through the API and the Console with no endpoint of its own.

◆ firmwareInstallationParameters()

std::vector< ProcedureParameter > mm::node::firmwareInstallationParameters ( )

What the procedure accepts, as its descriptor advertises it.

◆ firmwareInstallationSteps()

std::vector< ProgressStep > mm::node::firmwareInstallationSteps ( )

The procedure's step template, in order.

◆ firmwareLatencyParameters()

std::vector< ProcedureParameter > mm::node::firmwareLatencyParameters ( )

What measuring a firmware latency accepts, as its descriptor advertises it.

◆ firmwareLatencySteps()

std::vector< ProgressStep > mm::node::firmwareLatencySteps ( )

The firmware latency procedure's step template — start, observe, read, stop.

The union of four actions, and no run performs all of it. A measurement performs the first three, a raw action performs the one that names it, and the rest stay idle — which is honest about a run that never attempted them, and is why the ids name the actions rather than positions.

◆ fullFirmwareDescriptors()

FullFirmwareDescriptors mm::node::fullFirmwareDescriptors ( const HardwareDescription description,
const IntegroVariant variant 
)

Assembles the descriptors description accepts, appending variant's fieldbus character when there is one.

The fieldbus tail comes from the .variant file and nowhere else — §3.4.2.1 notes it "does not appear in the hardware description" — so a device without one (any drive that is not an Integro) yields descriptors of three fields, which is exactly what its packages are named with. Passing a null variant is therefore normal rather than a degraded mode.

Parameters
descriptionA parsed hardware description.
variantThe device's parsed .variant, or nullptr when it has none.
Returns
Both descriptors, ready to compare against a package name.

◆ hrdColumns()

std::vector< std::string_view > mm::node::hrdColumns ( somanet::HrdData  data)

The column names of one decoded sample of data, in the order a row carries them.

The rows go on the wire positionally — a 10 s recording is ten thousand of them — so the names travel once, beside the rows, exactly as the monitoring protocol ships its parameter order once.

◆ hrdStreamingParameters()

std::vector< ProcedureParameter > mm::node::hrdStreamingParameters ( )

What HRD streaming accepts, as its descriptor advertises it.

The advertised duration range is the wider of the two formats, since a descriptor carries one set of bounds per parameter; the parse applies the narrower one once the format is known.

◆ hrdStreamingSteps()

std::vector< ProgressStep > mm::node::hrdStreamingSteps ( )

The HRD streaming procedure's step template — configure, then record.

◆ icMuCalibrationModeParameters()

std::vector< ProcedureParameter > mm::node::icMuCalibrationModeParameters ( )

What setting an iC-MU calibration mode accepts, as its descriptor advertises it.

◆ icMuCalibrationModeSteps()

std::vector< ProgressStep > mm::node::icMuCalibrationModeSteps ( )

The iC-MU calibration mode procedure's step template — one step, idle.

◆ idleSnapshot()

ProcedureSnapshot mm::node::idleSnapshot ( std::vector< ProgressStep steps)

A well-formed snapshot for a procedure that never ran — idle, no timestamps, and every step idle from steps.

ProcedureManager cannot produce this — it is only told a step template when a run starts — so it is the job of whoever holds the template (the catalogue). With it, "never run" and "ran" have the same shape on the wire and a client renders one component with no empty-state branch, which is the whole point of the accumulating-snapshot model.

◆ ignoreBissStatusBitsParameters()

std::vector< ProcedureParameter > mm::node::ignoreBissStatusBitsParameters ( )

What ignoring BiSS status bits accepts, as its descriptor advertises it.

◆ ignoreBissStatusBitsSteps()

std::vector< ProgressStep > mm::node::ignoreBissStatusBitsSteps ( )

The ignore-BiSS-status-bits procedure's step template — one step, idle.

◆ insertBits()

void mm::node::insertBits ( std::span< uint8_t >  dst,
uint32_t  bitOffset,
uint16_t  bitLength,
std::span< const uint8_t >  value 
)

Inserts bitLength bits of value (LSB-first) into dst at bitOffset.

The inverse of extractBits. Bits of value beyond what it provides are treated as 0.

◆ integerParameter()

ProcedureParameter mm::node::integerParameter ( std::string  name,
std::string  title,
std::string  description,
nlohmann::json  defaultValue,
int64_t  minValue,
int64_t  maxValue 
)

A whole-number parameter accepting minValue to maxValue inclusive.

One factory per type, rather than a braced aggregate at each call site, because the fields are type-specific: only an integer has bounds, only an enum has options, only a byte array has a length. A factory makes the combination that applies the only one that can be written.

Parameters
defaultValueWhat an omitting request gets; pass nullptr to make it required.

◆ integroVariantOption()

const IntegroVariantOption * mm::node::integroVariantOption ( uint16_t  id)

Looks a code up in the catalogue.

The catalogue comes from the commissioning tooling's table, which is a superset of the firmware's own RuntimeVariantOptions enum — the enum does not list codes 21-26 or 39. The superset is what an older file needs to decode.

Parameters
idThe option code.
Returns
The catalogue entry, or nullptr for a code the catalogue does not name.

◆ integroVariantOptions()

std::span< const IntegroVariantOption > mm::node::integroVariantOptions ( )

The whole catalogue, in code order.

Serving it is the point: a client that wants to explain a decoded file, or simply show what an Integro can be licensed with, should not carry a second copy of this table.

Maintained by hand. It is vendor data copied into the master, so a firmware release that adds an option code leaves it stale until someone adds the row. That is a deliberate choice rather than an oversight: the catalogue's richest form — categories, SoC variables, part-number segments and mutual exclusions — exists only in the commissioning tooling's table, and nothing generatable carries it (the firmware's enum has ids and names alone, and the ESI does not describe variants at all). It fails softly, which is what makes the choice affordable: an unrecognised code still decodes and is still reported, as an id with no category or meaning, so a file from a newer firmware lists everything it selects rather than dropping what this build cannot name.

◆ isScalarDataType()

bool mm::node::isScalarDataType ( uint16_t  dataType)

Whether a value of dataType is stored in DeviceParameter::bits.

True for every arithmetic ETG.1020 type — all of which fit in eight bytes — and false for strings and for the composite / unknown types that fall through to raw bytes. This is what decides which of a parameter's two storage fields holds its value, and because dataType is immutable once the object dictionary is enumerated, the choice never changes: a value has exactly one home and the two fields can never disagree.

◆ kueblerRegisterParameters()

std::vector< ProcedureParameter > mm::node::kueblerRegisterParameters ( )

What a Kübler register access accepts, as its descriptor advertises it.

◆ kueblerRegisterSteps()

std::vector< ProgressStep > mm::node::kueblerRegisterSteps ( )

The Kübler register procedure's step template — one step, idle.

◆ listProcedures()

std::expected< std::vector< ProcedureListing >, ProcedureError > mm::node::listProcedures ( DeviceManager deviceManager,
ProcedureManager procedureManager,
uint16_t  devicePosition 
)

Every procedure devicePosition supports, each with its current or last-run snapshot.

Returns
The listings (empty if the device supports none), or kUnknownDevice.

◆ makeParameterKey()

constexpr uint32_t mm::node::makeParameterKey ( uint16_t  index,
uint8_t  subindex 
)
constexpr

Packs an object dictionary index and subindex into a single 32-bit key.

Layout: (index << 8) | subindex. Used as the key of Device::parameters().

◆ motorPhaseOrderDetectionSteps()

std::vector< ProgressStep > mm::node::motorPhaseOrderDetectionSteps ( )

Motor phase order detection's step template — prepare, release the brake, detect, restore.

◆ numericValue()

std::optional< double > mm::node::numericValue ( const DeviceParameterValue value)

Coerces a DeviceParameterValue to a double, when it holds a number.

Returns
The value as a double for any arithmetic alternative, or std::nullopt for std::string / std::vector<uint8_t>.

◆ offsetDetectionSteps()

std::vector< ProgressStep > mm::node::offsetDetectionSteps ( )

The commissioning sequence's step template — every command in the order it runs, plus the shared prepare, brake and restore steps.

◆ openFirmwarePackage()

std::expected< FirmwarePackage, std::string > mm::node::openFirmwarePackage ( std::span< const uint8_t >  zip,
std::span< const std::string >  skipFiles 
)

Reads a firmware package zip held in memory, dropping the entries named in skipFiles.

Skipping happens during extraction rather than after it, so a skipped entry is never decompressed — which is most of the point, since the two default-skipped files are the largest in a typical package.

One content check is made here rather than left to the caller: a zip with no app_*.bin entry at all is rejected, because that is not a firmware package and saying so before a device is taken to BOOT is far better than discovering it afterwards. An app_*.bin that is present but skipped is fine — that is a deliberate request to install only the rest.

Parameters
zipPackage bytes.
skipFilesEntry names to leave out, compared exactly.
Returns
The classified contents, or a message describing what made the zip unreadable.

◆ openPhaseDetectionSteps()

std::vector< ProgressStep > mm::node::openPhaseDetectionSteps ( )

Open phase detection's step template — prepare, check, restore, all idle.

◆ operationModes()

std::expected< OperationModes, std::string > mm::node::operationModes ( DeviceManager deviceManager,
uint16_t  slavePosition 
)

Borrow-and-delegate wrapper over deviceOperationModes, for a caller holding a bus position rather than a device (the HTTP layer).

◆ operator<<()

std::ostream & mm::node::operator<< ( std::ostream &  os,
const ProcedureError e 
)
inline

Streams the message, so ASSERT_TRUE(r) << r.error() and spdlog {} work unchanged.

◆ osCommandErrorName()

std::optional< std::string_view > mm::node::osCommandErrorName ( uint8_t  code)

Names a general OS error code, or std::nullopt when code is command-specific.

A caller that knows which command it issued should try its own error table first and fall back to this one; a caller that does not can report the raw code alongside whatever this returns.

◆ osCommandParameters()

std::vector< ProcedureParameter > mm::node::osCommandParameters ( )

What the OS command procedure accepts, as its descriptor advertises it.

Lives beside parseOsCommandRequest deliberately: the description a client builds a form from and the validation a request is actually held to are two views of one thing, and keeping them apart is how they drift.

◆ osCommandSteps()

std::vector< ProgressStep > mm::node::osCommandSteps ( )

The OS command procedure's step template — one step, all idle.

◆ packLeBits()

uint64_t mm::node::packLeBits ( std::span< const uint8_t >  bytes)

Packs up to eight raw little-endian wire bytes into a uint64_t (zero-extended).

◆ packMappingEntry()

uint32_t mm::node::packMappingEntry ( const PdoMappingEntry e)
inline

Packs an entry into its 32-bit CoE mapping word (ETG.1000.6 §5.6.7.4.7): index<<16 | subindex<<8 | bitLength.

bitOffset is not part of the wire word — it is derived from the running offset by the reader. This is the word Device::writePdoMapping writes to each mapping-object subindex.

◆ parameterOriginName()

std::string_view mm::node::parameterOriginName ( ParameterOrigin  origin)

Returns the string form of origin ("objectDictionary" / "sii").

◆ parseCia402Command()

std::optional< Cia402Command > mm::node::parseCia402Command ( std::string_view  token)

Parses a command token ("enable" / "disable" / "quickStop" / "faultReset").

Returns
The command, or std::nullopt if the token is unrecognised.

◆ parseCia402TargetKind()

std::optional< Cia402TargetKind > mm::node::parseCia402TargetKind ( std::string_view  token)

Parses a target-kind token ("position" / "velocity" / "torque").

Returns
The kind, or std::nullopt if the token is unrecognised.

◆ parseDeviceFileList()

std::vector< DeviceFile > mm::node::parseDeviceFileList ( std::string_view  text)

Parses the body of a fs-getlist read into one entry per line.

Pure, so the one place that knows the firmware's listing format is testable without a device. Each line is <filename>, size: <bytes>; a line that does not end that way is taken whole as a filename with no size, rather than dropped — a name is what a caller needs, and a firmware that formats a line unexpectedly should not make the files around it unreachable. Blank lines are skipped and CRLF is accepted.

Parameters
textThe pseudo-file's contents.
Returns
One entry per non-blank line, in the order they appeared.

◆ parseEncoderRegisterRequest()

std::expected< EncoderRegisterRequest, std::string > mm::node::parseEncoderRegisterRequest ( const nlohmann::json &  body)

Parses and validates a client's encoder register request body.

Accepts {"encoder": 1, "write": false, "registerAddress": 117, "value": 7}. Only registerAddress is required; the rest default as EncoderRegisterRequest declares, which is exactly what encoderRegisterParameters advertises.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseFirmwareInstallationRequest()

std::expected< FirmwareInstallationRequest, std::string > mm::node::parseFirmwareInstallationRequest ( const nlohmann::json &  body)

Parses and validates a client's installation request.

Accepts {"packageContent": "<base64 zip>", "packageFilename": "package_….zip", "skipFiles": [...], "cachePackage": true, "finalState": "preop"}. Every field is optional except that **one of packageContent or packageFilename must resolve to a package**: packageContent wins when both are given, and a lone packageFilename is looked up in firmwareCacheDir, so re-installing a package already on the server costs no upload.

Resolving the bytes here rather than in the body is deliberate: "the package you named is not cached" is a bad request, answerable immediately, not a run that starts and then fails.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseFirmwareLatencyAction()

std::optional< FirmwareLatencyAction > mm::node::parseFirmwareLatencyAction ( std::string_view  token)

Parses a firmware latency action token. std::nullopt if it names none of them.

◆ parseFirmwareLatencyRequest()

std::expected< FirmwareLatencyRequest, std::string > mm::node::parseFirmwareLatencyRequest ( const nlohmann::json &  body)

Parses and validates a client's firmware latency request body.

Accepts {"action": "measure", "latency": "setpoint", "durationMs": 2000}. Every field is optional and defaults as FirmwareLatencyRequest declares.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseFirmwarePackageName()

std::expected< FirmwarePackageName, std::string > mm::node::parseFirmwarePackageName ( std::string_view  filename)

Decodes filename as a SOMANET firmware package name.

A Windows duplicate-download suffix (" (1)" before the extension) is removed first, because a user who downloaded the same package twice should not be told their file is unrecognised.

Whether a name parses matters for exactly one thing: a package is only cached under a name that decodes, so the cache cannot fill with files named anything at all. A package whose name does not parse still installs — the bytes are what get written, and the name is metadata.

Parameters
filenameBare filename, with no directory part.
Returns
The decoded fields, or a message saying which part of the grammar filename missed.

◆ parseFsBufferTransfer()

std::optional< FsBufferTransfer > mm::node::parseFsBufferTransfer ( std::string_view  token)

Reads an fs-buffer direction back from its name. std::nullopt if token names none.

◆ parseHardwareDescription()

std::expected< HardwareDescription, std::string > mm::node::parseHardwareDescription ( std::string_view  content)

Decodes content as a .hardware_description file.

Three things fail a parse: content that is not JSON, content with no device object, and a device carrying no id or no version. Everything else is accepted as written, including a missing fileVersion and missing optional fields.

**The fileVersion major is read but not enforced.** §3.2.1 says a major bump "reflects a change in the existing names. A new parser is needed" — but refusing an unknown major would make a drive flashed with a future file unreadable today, in exchange for guarding fields (id, version, keyId) that a rename would be gratuitous to touch. The version is reported so a caller that cares can decide; nothing here decides for it.

The three required fields are exactly what a descriptor is built from, which is also what makes this a usable type check: arbitrary JSON does not carry a device with an id and a version, so a file that is not a hardware description is rejected rather than silently yielding an empty descriptor that matches no package.

Parameters
contentThe file's bytes as text; UTF-8 per §3.1.
Returns
The parsed description, or what made content unusable.

◆ parseHrdStreamingRequest()

std::expected< HrdStreamingRequest, std::string > mm::node::parseHrdStreamingRequest ( const nlohmann::json &  body)

Parses and validates a client's HRD streaming request body.

Accepts {"data": "encoder-raw", "durationMs": 5000} — or system-identification. Both fields are required, and the duration is checked against the limit for the chosen data, which is 6000 ms for system identification and 10000 ms for encoder raw. The drive applies the same two limits itself, so checking here only turns a rejected round trip into a 400 that names the limit for the data actually chosen.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseIcMuCalibrationModeRequest()

std::expected< IcMuCalibrationModeRequest, std::string > mm::node::parseIcMuCalibrationModeRequest ( const nlohmann::json &  body)

Parses and validates a client's iC-MU calibration mode request body.

Accepts {"encoder": 1, "mode": "configuration"} — or raw, or standard. mode is required; encoder defaults to encoder 1.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseIgnoreBissStatusBitsRequest()

std::expected< IgnoreBissStatusBitsRequest, std::string > mm::node::parseIgnoreBissStatusBitsRequest ( const nlohmann::json &  body)

Parses and validates a client's ignore-BiSS-status-bits request body.

Accepts {"encoder": 1, "ignore": true}. ignore is required; encoder defaults to encoder 1.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseIntegroVariant()

std::expected< IntegroVariant, std::string > mm::node::parseIntegroVariant ( std::span< const uint8_t >  content)

Decodes content as a .variant file.

The option codes are left in file order rather than sorted. They arrive unsorted — a real file reads 1, 17, 34, 4, 7, 10, 14 — and the order is the only record of how the file was written, so sorting is left to whoever displays them.

Trailing bytes past the last option are accepted. Every file seen ends exactly at 132 + 2 × count, but the firmware reads only as many options as the count claims and ignores the rest, so refusing padding would reject a file the drive is happy with.

Parameters
contentThe file's bytes.
Returns
The decoded file, or why content is not one.

◆ parseKueblerRegisterRequest()

std::expected< KueblerRegisterRequest, std::string > mm::node::parseKueblerRegisterRequest ( const nlohmann::json &  body)

Parses and validates a client's Kübler register request body.

Accepts {"address": 48, "length": 4, "write": false, "value": 0}. address and length are required — the width is not inferred from the register map, because the map is a vendor draft and the command addresses bytes the draft does not document.

GET /api/meta/kuebler-registers is the map a client builds its picker from; it carries each register's width, so a picker fills both fields.

◆ parseOsCommandRequest()

std::expected< OsCommandRequest, std::string > mm::node::parseOsCommandRequest ( const nlohmann::json &  body)

Parses and validates a client's OS command request body.

Lives here rather than in the HTTP handler because validation is domain knowledge — how many bytes a command is, what a byte may hold, what timing is sane — and the handler's job is only to forward. A C++ caller building a request directly gets the same checks.

Accepts {"command": [8, 0, ...], "timeoutMs": 30000, "pollIntervalMs": 10, "fsBuffer": "read", "fsBufferData": "<base64>"}. Everything but command is optional and defaults as OsCommandRequest declares.

fsBuffer is "none", "read" or "write". fsBufferData carries the bytes to send, base64-encoded because JSON has no binary type; it is required for "write" and rejected for the other two, so a caller who sets one and forgets the other is told rather than silently running a command that moves nothing.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseRestoreDefaultParametersRequest()

std::expected< RestoreDefaultParametersRequest, std::string > mm::node::parseRestoreDefaultParametersRequest ( const nlohmann::json &  body)

Parses and validates a client's restore request body.

Accepts {"group": "all"} — or communication, application, manufacturer. The group is optional and defaults as RestoreDefaultParametersRequest declares.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseRestoreGroup()

std::optional< RestoreGroup > mm::node::parseRestoreGroup ( std::string_view  token)

Parses a restore-group token ("all" / "communication" / "application" / "manufacturer") into a RestoreGroup. Returns std::nullopt for any other token.

◆ parseSkippedCyclesRequest()

std::expected< SkippedCyclesRequest, std::string > mm::node::parseSkippedCyclesRequest ( const nlohmann::json &  body)

Parses and validates a client's skipped cycles request body.

Accepts {"service": "drive-control"} — or motion-control. The field is optional.

Validating it here is not ceremony: each firmware service answers only requests naming itself, so a byte naming neither is answered by nothing at all and costs the drive's whole command timeout before surfacing as a timeout error that says nothing about the real mistake.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseSystemIdentificationRequest()

std::expected< SystemIdentificationRequest, std::string > mm::node::parseSystemIdentificationRequest ( const nlohmann::json &  body)

Parses and validates a client's system identification request body.

Accepts {"startFrequencyMilliHz": 1000, "targetFrequencyMilliHz": 100000, "targetAmplitudePermil": 50, "transitionTimeMs": 5000, "signalType": "logarithmic", "start": "after-hrd-stream-start"}. The four numbers are required; signalType and start default.

The bounds checked here are the firmware's own, and checking them is not politeness. The drive stores each setting without looking at it and validates the set on the rising edge of the start parameter — where a bad one raises IvldPara with a quick-stop reaction. Rejecting the request is the difference between a 400 and a faulted drive.

Parameters
bodyParsed request JSON.
Returns
The validated request, or a message naming what is wrong with it.

◆ parseTriggerErrorRequest()

std::expected< TriggerErrorRequest, std::string > mm::node::parseTriggerErrorRequest ( const nlohmann::json &  body)

Parses and validates a client's trigger-error request body.

Accepts {"service": "drive-control", "errorType": "resettable-firmware-error"}. errorType is required; service defaults to drive control.

◆ parseVelocitySourceRequest()

std::expected< VelocitySourceRequest, std::string > mm::node::parseVelocitySourceRequest ( const nlohmann::json &  body)

Parses and validates a client's velocity source request body.

Accepts {"source": "firmware"} — or encoder. Required.

◆ phaseInductanceMeasurementSteps()

std::vector< ProgressStep > mm::node::phaseInductanceMeasurementSteps ( )

Phase inductance measurement's step template — prepare, measure, restore, all idle.

◆ phaseResistanceMeasurementSteps()

std::vector< ProgressStep > mm::node::phaseResistanceMeasurementSteps ( )

Phase resistance measurement's step template — prepare, measure, restore, all idle.

◆ polePairDetectionSteps()

std::vector< ProgressStep > mm::node::polePairDetectionSteps ( )

Pole pair detection's step template — prepare, release the brake, detect, restore.

◆ procedureCatalogue()

const std::vector< ProcedureCatalogueEntry > & mm::node::procedureCatalogue ( )

Every procedure the server knows, in the order a client should present them.

A stable reference to a table built once on first use; entries are never added or removed at runtime, so a caller may hold the reference.

◆ procedureSnapshot()

std::expected< ProcedureSnapshot, ProcedureError > mm::node::procedureSnapshot ( DeviceManager deviceManager,
ProcedureManager procedureManager,
uint16_t  devicePosition,
std::string_view  name 
)

The current or last-run state of one procedure on one device.

Never-run is not an error: it reports the descriptor's all-idle snapshot, so a client polls one shape whether or not the procedure has ever been run. kUnknownProcedure is reserved for a name that does not exist or that this device does not support — a genuine addressing mistake.

◆ readFileList()

std::expected< std::vector< DeviceFile >, std::string > mm::node::readFileList ( DeviceManager deviceManager,
uint16_t  slavePosition 
)

Reads the list of files stored on a device (FoE read of "fs-getlist").

Thin forward to SomanetDrive::readFileList. Vendor-specific despite reading like a filesystem primitive: the listing is a pseudo-file Synapticon firmware serves, not a standard service, so a device that is not a SOMANET drive is refused rather than asked.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
Returns
The files the device reported, or why the listing could not be read.

◆ readHardwareDescription()

std::expected< HardwareDescription, std::string > mm::node::readHardwareDescription ( DeviceManager deviceManager,
uint16_t  slavePosition 
)

Reads and parses a device's .hardware_description file.

Thin forward to SomanetDrive::readHardwareDescription — what the device says it is, and the source of the descriptor that decides which firmware belongs on it.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
Returns
The parsed description, or why it could not be read.

◆ readHrdRecording()

std::expected< HrdRecording, std::string > mm::node::readHrdRecording ( DeviceManager deviceManager,
uint16_t  slavePosition,
somanet::HrdData  data 
)

Reads a drive's high resolution data recording back and decodes it.

Thin forward to SomanetDrive::readHrdRecording. Blocks for the transfer — up to five 8 KB FoE reads plus the listing — which is why it is not the tail of the recording procedure: a recording is worth reading more than once, and a run's snapshot is no place to keep ten thousand samples.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
dataWhich layout the files hold — the selection the recording was made with.
Returns
The decoded recording, or why it could not be read.

◆ readIntegroVariant()

std::expected< std::optional< IntegroVariant >, std::string > mm::node::readIntegroVariant ( DeviceManager deviceManager,
uint16_t  slavePosition 
)

Reads and parses a device's .variant file.

Thin forward to SomanetDrive::readIntegroVariant. Only Integro drives carry one; an empty optional means the device has none — which a Node or a Circulo correctly does, and which is therefore not a failure. Read its documentation for why any unreadable variant is reported that way rather than only a not-found one.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
Returns
The parsed file, nothing if the device has none, or why the read failed.

◆ readObjectDictionarySteps()

std::vector< ProgressStep > mm::node::readObjectDictionarySteps ( )

The read-object-dictionary procedure's step template — one step, idle.

◆ reconcileDetectedModules()

std::expected< int, std::string > mm::node::reconcileDetectedModules ( const Device device)

Reconciles a device's Configured Module Ident List with its Detected list.

Walks the EtherCAT Modular Device Profile objects (ETG.5001): for every populated slot in the Detected Module Ident List (0xF050) it writes the detected ident into the matching subindex of the Configured Module Ident List (0xF030). A drive whose configured and detected lists disagree reports a module mismatch and refuses to leave PRE-OP; copying detected into configured clears it.

The device must be in PRE-OP or higher (SDO mailbox active) — 0xF030 is writable in PRE-OP. Vendor-neutral: keyed only on the standard MDP objects, never on vendor ID. Best-effort and idempotent: a device that does not implement 0xF050 (i.e. is not modular) is treated as success with zero slots written, and slots whose configured entry already matches the detected one are left untouched.

Parameters
deviceTarget device; must have mailbox communication active (PRE-OP+).
Returns
The number of configured-list subindices written, or an error string naming the slot(s) whose write to 0xF030 failed.

◆ releaseBrake()

std::expected< BrakeState, std::string > mm::node::releaseBrake ( DeviceManager deviceManager,
uint16_t  slavePosition,
std::chrono::milliseconds  settle 
)

Releases (disengages) a drive's brake, then waits for the release to finish.

Thin forward to SomanetDrive::releaseBrake — read its documentation before calling this, because two of its properties are surprising. The release only actually happens while the drive is in OP ENABLED (elsewhere the write merely energises phase D), and on a pin brake the release procedure moves the shaft. A brake that is not firmware-controlled is left alone, which the returned state reports rather than treating as a failure.

Blocks for the drive's pull time (0x2004:03) plus settle.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
settleExtra wait on top of the drive's pull time.
Returns
The brake state read back afterwards, or why the attempt failed.

◆ removeDeviceFile()

std::expected< void, std::string > mm::node::removeDeviceFile ( Device device,
const std::string &  filename 
)

Deletes a file from a SOMANET drive's flash (FoE read of "fs-remove=<filename>").

A vendor pseudo-file like fs-getlist, and a read rather than a write, because FoE has no delete: the firmware acts on the name the read carries. This is the one place that knows the prefix, so no caller has to.

**Takes a Device rather than being a SomanetDrive method, on purpose.** Building a SomanetDrive validates the CiA402 dictionary, which a drive in BOOT has not enumerated — and BOOT is exactly where firmware installation deletes the files a package replaces. A profile view would make removal fail where it is needed most. Everything this needs is FoE, which the bootloader serves.

A file that was not there is success. The caller asked for the file to be gone, and it is. Every other FoE failure is reported.

Parameters
deviceThe drive to delete from.
filenameName as the drive lists it, with no prefix.
Returns
Void once the file is gone, or why the removal failed.

◆ removeFile()

std::expected< void, std::string > mm::node::removeFile ( DeviceManager deviceManager,
uint16_t  slavePosition,
const std::string &  filename 
)

Deletes one file from a device's flash.

Thin forward to SomanetDrive::removeFile. Vendor-specific for the same reason as readFileList: the drive has no delete operation, only a pseudo-file that acts on the name it carries. A file that was not there counts as removed.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
filenameName as the drive lists it, with no prefix.
Returns
Void once the file is gone, or why the removal failed.

◆ restoreDefaultParametersParameters()

std::vector< ProcedureParameter > mm::node::restoreDefaultParametersParameters ( )

What restoring default parameters accepts, as its descriptor advertises it.

◆ restoreDefaultParametersSteps()

std::vector< ProgressStep > mm::node::restoreDefaultParametersSteps ( )

Restore default parameters' step template — one step, idle.

◆ runCia402Command()

std::expected< Cia402Status, std::string > mm::node::runCia402Command ( DeviceManager deviceManager,
uint16_t  slavePosition,
Cia402Command  command,
std::chrono::milliseconds  timeout = std::chrono::milliseconds(2000) 
)

Runs a CiA402 state-machine command (enable / disable / quick stop / fault reset), then reads back the resulting snapshot.

kEnable walks every intermediate transition to OperationEnabled (up to timeout, clearing a fault first if needed); the others issue a single controlword edge. The drive must be exchanging for kEnable to make progress.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
commandThe action to perform.
timeoutMaximum time to wait for kEnable to reach OperationEnabled.
Returns
The post-command snapshot, or an error string if the device is unknown, not a CiA402 drive, or the command fails (including an enable timeout).

◆ runCommutationOffsetMeasurementProcedure()

std::expected< void, std::string > mm::node::runCommutationOffsetMeasurementProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs commutation offset measurement as a procedure body — OS command 5 and nothing else.

One command, like every other measurement procedure here. The pairing with motor phase order detection (4) lives in runOffsetDetectionProcedure, which runs the whole commissioning sequence; running the two on their own is the caller's to sequence.

Command 5 is only meaningful once the phase order is established, and the drive does not verify that. An offset measured against an unknown phase order is simply wrong, and nothing here can tell the difference — 0x2003:05 holds a valid value either way, so there is no "never established" to detect. Run motor phase order detection first, or run offset detection.

The one procedure whose physical behaviour is configured on the drive rather than fixed here: the method in 0x2009:03 decides whether the measurement turns the rotor and whether it needs the brake released. So the method is read first — before the drive is touched at all, since a method that cannot be read or is out of range means the brake would be handled by guesswork — and is reported with the result.

The brake is released only for the rotating methods (0x2009:03 = 0 or 1), which the firmware refuses to run with it engaged. The stationary method (2) needs nothing of the brake, so the brake is never written and the load stays held; its release-brake step stays idle, and there is nothing about the brake to restore either.

A successful run changes the drive's configuration — 0x2001 written and 0x2009:01 set to OFFSET_VALID, in the object dictionary rather than in flash — and the restore deliberately leaves both alone: they are the result, not side effects.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between steps and passed into the OS command so a running measurement is aborted rather than abandoned.
Returns
Void when the drive reported an offset, otherwise why it did not.

◆ runEncoderRegisterProcedure()

std::expected< void, std::string > mm::node::runEncoderRegisterProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const EncoderRegisterRequest request 
)

Runs one encoder register access as a procedure body.

The one procedure here that prepares nothing. OS command 0's only restrictions are that the addressed encoder is configured and that it is a BiSS encoder — no diagnostics mode, no Operation Enabled, no brake, and no motion — so there is no preparation to do and nothing to restore, and it runs from PRE-OP up on a drive that may be exchanging process data. Its single step is the access itself.

A read and a write are one procedure because they are one firmware command, told apart by EncoderRegisterRequest::write; the drive answers both by reporting what the register holds, so a write confirms itself.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command so an in-flight access is aborted, not merely abandoned.
requestWhich encoder, which register, and whether to write it.
Returns
Void when the drive performed the access, otherwise why it did not.

◆ runFirmwareInstallationProcedure()

std::expected< void, std::string > mm::node::runFirmwareInstallationProcedure ( DeviceManager deviceManager,
uint16_t  devicePosition,
ProgressReporter reporter,
std::stop_token  stop,
const FirmwareInstallationRequest request 
)

Installs request's package on the device at devicePosition.

Takes the device to BOOT, writes what the package holds, and leaves it in request.finalState. Borrows the device per step and holds nothing in between, which is what lets it transition — and which means a rescan can interleave; the next borrow then fails and the run ends cleanly.

The steps and their failure policy, which is not uniform on purpose:

  • package, cache — offline; a package that will not open fails before anything is touched on the bus.
  • boot — fatal. Nothing can be written without it.
  • extra-filesbest effort. These are descriptive files (an ESI, a picture); a failure is recorded in the step's value and the install continues, because aborting a firmware update over a picture would be worse than not having the picture.
  • sii, app-firmware, com-firmware — fatal. These are the firmware.
  • final-state — fatal, but reported so it cannot be confused with a write failure: the bytes are on the drive either way, and which of the two happened changes what a user does next.

Whatever went wrong, the device is not left in BOOT unless that is what was asked for: a failure after entering BOOT still attempts the final transition on the way out.

◆ runFirmwareLatencyProcedure()

std::expected< void, std::string > mm::node::runFirmwareLatencyProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const FirmwareLatencyRequest request 
)

Measures one internal firmware latency as a procedure body.

Prepares nothing, restores nothing, needs no operation mode, no CiA402 state and no brake, and moves nothing — the measurement is two timer reads inside a cycle the drive control service was running anyway. It runs from PRE-OP up on a drive that may be exchanging process data.

What the figure is worth depends on what the drive was doing while it collected, which this procedure does not arrange: measuring an idle drive for two seconds reports the worst case of an idle drive. A maximum only means something over a window that contained the load it is meant to characterise — which is what FirmwareLatencyAction::kStart and kReadMaximum exist for.

A measurement is left running. The read action does not stop it and stopping is not per-latency, so a kMeasure run leaves the drive measuring rather than silently ending a measurement of the other latency that something else may be collecting. See SomanetDrive::readMaximumFirmwareLatency.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked during the observation window and passed into each command.
requestWhich action, which latency, and for how long.
Returns
Void once the requested action completed, otherwise why it did not.

◆ runHrdStreamingProcedure()

std::expected< void, std::string > mm::node::runHrdStreamingProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const HrdStreamingRequest request 
)

Records one high resolution data stream as a procedure body.

Two steps because the firmware has two commands: configuring arms the recording and deletes the files of the previous one (seconds of work on its own), and starting it records for the whole requested duration. Splitting them in the report is what makes a run that failed to arm distinguishable from one that failed while recording.

Prepares nothing and moves nothing, like runEncoderRegisterProcedure — but what the recording is worth depends on preparation this procedure does not do: encoder raw data records zeros unless the encoder was first put into raw mode (runIcMuCalibrationModeProcedure), and system identification data records an unexcited drive unless a system identification run was configured and started first. See somanet::HrdData.

The recording is left on the drive. This body does not read it back — the files are read through readHrdRecording, which needs the same data selection to decode them, and the configure step reports what was used so a client that polled the run knows what to ask for.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into both commands, so cancelling during the recording aborts it on the drive and leaves a short recording behind.
requestWhich signal to record, and for how long.
Returns
Void once the recording finished, otherwise why it did not.

◆ runIcMuCalibrationModeProcedure()

std::expected< void, std::string > mm::node::runIcMuCalibrationModeProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const IcMuCalibrationModeRequest request 
)

Sets an iC-MU encoder's calibration mode as a procedure body.

Prepares nothing and moves nothing, like runEncoderRegisterProcedure — the command needs only an active mailbox — but it differs from every other procedure here in one way worth stating plainly: it has no restore. Configuration and raw are modes an encoder is left in, so a run that puts one there changes how the drive reads position until another run puts it back to standard.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command so an in-flight change is aborted.
requestWhich encoder, and which mode to put it in.
Returns
Void once the drive applied the mode, otherwise why it did not.

◆ runIgnoreBissStatusBitsProcedure()

std::expected< void, std::string > mm::node::runIgnoreBissStatusBitsProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const IgnoreBissStatusBitsRequest request 
)

Starts or stops ignoring a BiSS encoder's status bits as a procedure body.

Prepares nothing and moves nothing — the command needs only an active mailbox, and runs from PRE-OP up on a drive that may be exchanging process data. Like runIcMuCalibrationModeProcedure it has no restore: ignoring is a state the encoder is left in until another run ends it or the drive is power-cycled.

What it suppresses is a fault, not a nuisance. See SomanetDrive::setIgnoreBissStatusBits: a BiSS error bit otherwise faults the drive into active short circuit, and ignoring the bits means the drive keeps running on an encoder that is reporting its own position as unreliable.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command so an in-flight change is aborted.
requestWhich encoder, and which way.
Returns
Void once the drive applied the change, otherwise why it did not.

◆ runKueblerRegisterProcedure()

std::expected< void, std::string > mm::node::runKueblerRegisterProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const KueblerRegisterRequest request 
)

Reads or writes one Integro internal-encoder register as a procedure body.

Prepares nothing and moves nothing, like runEncoderRegisterProcedure — its BiSS counterpart — and runs from PRE-OP up on a drive that may be exchanging process data. The step records the bytes as they came off the wire, the assembled value, and the register's name when the vendor's draft documents the address.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command.
requestWhich register, how wide, and which direction.
Returns
Void once the encoder performed the access, otherwise why it did not.

◆ runMotorPhaseOrderDetectionProcedure()

std::expected< void, std::string > mm::node::runMotorPhaseOrderDetectionProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs motor phase order detection as a procedure body.

Four steps, with a brake release like runPolePairDetectionProcedure and for the same reason — this command's restrictions require a disengaged brake, and diagnostics mode suppresses the automatic release. The brake and the operation mode are put back on every path out.

This is the first procedure whose success changes the drive's configuration. The firmware writes the detected order into 0x2003:05 itself, so there is nothing to save afterwards — and nothing to undo either: the restore puts back the mode and the brake, not the phase order, because the new value is the result the run was for. It is also a prerequisite: commutation offset measurement requires that this ran first.

The command rotates the rotor, so the shaft must be free and its load safe to move.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between steps and passed into the OS command so a running detection is aborted rather than abandoned.
Returns
Void when the drive reported a phase order, otherwise why it did not.

◆ runOffsetDetectionProcedure()

std::expected< void, std::string > mm::node::runOffsetDetectionProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs the whole commissioning sequence as one procedure body.

Every measurement a motor needs, in the order they depend on each other, in one prepared session: open phase detection (6), phase resistance (8), phase inductance (9), pole pair detection (7), motor phase order detection (4), commutation offset measurement (5). Each step records its own result, so a run that stops half way still reports everything it established.

Why one procedure rather than six runs. The drive is put into diagnostics mode and enabled once, and the brake is released once, so the axis spends the minimum time in a state where it can move; and the sequence cannot be got wrong — open phase detection before the measurements that assume connected phases, and motor phase order before the offset that is meaningless without it.

The brake is released as late as the sequence allows, not at the start: open phase detection and the two winding measurements do not require it, so the load stays held until pole pair detection needs it free. It is put where the offset method needs it before the last step, and restored to what it was on the way out.

A stopping failure stops the run. Every step depends on the ones before it, so a failed measurement is not skipped past — carrying on would measure against a value that was never established. An open phase fails the run outright for the same reason.

What it does not do is store the measurements. Commands 7, 8 and 9 report a value without writing it (unlike 4 and 5, which the firmware stores itself), and the objects it would belong in — 0x2003:01, :03 and :04 — hold their values in units this code never confirmed against the firmware. Writing an unverified scaling into a motor's configuration is worse than reporting the number and letting the caller place it.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between every step and passed into each command so a running measurement is aborted rather than abandoned.
Returns
Void when every step succeeded, otherwise why the run stopped.

◆ runOpenPhaseDetectionProcedure()

std::expected< void, std::string > mm::node::runOpenPhaseDetectionProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs open phase detection as a procedure body.

Prepares the drive, runs the check, and puts everything back:

  1. prepare — saves the current operation mode, sets somanet::OperationMode::kDiagnostics, and walks the CiA402 state machine to Operation Enabled. Diagnostics mode and Operation Enabled are both preconditions the firmware enforces by refusing the command with OS error 251.
  2. open-phase-detection — the OS command. An open phase fails this step, naming the offending terminal or FET: the check ran and found a fault, which is a result the user must act on, so it is not reported as a success carrying bad news.
  3. restore — puts back the operation mode as it was found and returns the drive to Switch On Disabled. It runs on every path out, including a failure or a cancellation, because a procedure that leaves a drive in diagnostics mode is worse than one that never ran.

The brake is not touched. This command's restrictions do not require a disengaged one, and the firmware specification says only that the command "might rotate the motor if there is no brake, or if it's disengaged" — so an engaged brake does not prevent the check, it keeps the shaft still while it runs. Contrast runPolePairDetectionProcedure, whose command does require it.

Needs the bus exchanging process data: the CiA402 state machine only advances while the statusword is updating, so a device that is not in OP will fail at step 1 rather than hanging.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between steps and passed into the OS command so a running check is aborted rather than abandoned.
Returns
Void when the drive found no open phase, otherwise why not.

◆ runOsCommandProcedure()

std::expected< void, std::string > mm::node::runOsCommandProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const OsCommandRequest request 
)

Runs one raw OS command as a procedure body.

Binds a SomanetDrive to device, issues request through SomanetDrive::runOsCommand, and records the outcome on the single kOsCommandStep step. A command the drive answered with an error is still a failure of the run — the step carries the decoded reason and the run ends as failed — while a timeout or a cancellation ends it the way ProcedureManager decides from the returned error and the stop token.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed through so an in-flight command is aborted, not merely abandoned.
requestThe command bytes and timing.
Returns
Void when the drive completed the command without error, otherwise why not.

◆ runPhaseInductanceMeasurementProcedure()

std::expected< void, std::string > mm::node::runPhaseInductanceMeasurementProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs phase inductance measurement as a procedure body.

Structurally identical to runPhaseResistanceMeasurementProcedure — the same three steps, the same preparation, and the same deliberate refusal to touch the brake, which this command no more requires than that one does. Only the quantity measured differs.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between steps and passed into the OS command so a running measurement is aborted rather than abandoned.
Returns
Void when the drive reported an inductance, otherwise why it did not.

◆ runPhaseResistanceMeasurementProcedure()

std::expected< void, std::string > mm::node::runPhaseResistanceMeasurementProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs phase resistance measurement as a procedure body.

Three steps: the shared prepare (diagnostics mode, Operation Enabled), the measurement, and the shared restore, which runs on every path out including a failure or a cancellation.

The brake is not touched, and that is the firmware's requirement rather than an omission. Unlike motor phase order and pole pair detection, this command does not ask for a released brake, so releasing one here would drop whatever it holds for no benefit — and an engaged brake steadying the shaft while current is driven into the windings is the better state to measure in. The one consequence worth knowing is that a loose shaft can still turn.

Needs the bus exchanging process data: the CiA402 state machine only advances while the statusword is updating, so a device that is not in OP will fail at the prepare step rather than hanging.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between steps and passed into the OS command so a running measurement is aborted rather than abandoned.
Returns
Void when the drive reported a resistance, otherwise why it did not.

◆ runPolePairDetectionProcedure()

std::expected< void, std::string > mm::node::runPolePairDetectionProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs pole pair detection as a procedure body.

Four steps, and the only measurement procedure here that releases the brake: this command's restrictions do require a disengaged one, and in diagnostics mode enabling the drive does not release it the way normal operation does, so the master has to. It is released after Operation Enabled (never before — the write only performs a real release from that state) and put back by the restore step on every path out, including a failure or a cancellation.

The command turns the rotor. The specification says it needs to, not that it might, so the shaft must be free and whatever it drives must be safe to move. On a vertical or loaded axis, support the load before running it: the brake is released for the duration.

Needs the bus exchanging process data, for the same reason as its siblings — the CiA402 state machine only advances while the statusword is updating.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between steps and passed into the OS command so a running detection is aborted rather than abandoned.
Returns
Void when the drive reported a pole pair count, otherwise why it did not.

◆ runReadObjectDictionaryProcedure()

std::expected< void, std::string > mm::node::runReadObjectDictionaryProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Reads every object dictionary value in one transfer, as a procedure body.

This exists to exercise the fs-buffer transfer, not because it is the way to read parameters. CoE Complete Access already reads a whole object at a time, and that is what the parameter cache uses. What this run proves is that the drive can hand over bulk data while a command is running, which is the mechanism every safety-module command depends on. It also reaches two values SDO cannot: 0x1024, which is write-only, and 0x1023:01.

Harmless: a pure read, no operation mode, no CiA402 state, no brake, and nothing restored. It runs from PRE-OP up, needing only an active mailbox.

A run that fails on the decode rather than on the wire is still useful information, and the step's message says which: it means this master's record of the device's object dictionary disagrees with the drive's own. See SomanetDrive::readObjectDictionaryValues.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command so an in-flight read is aborted.
Returns
Void once every value was read and decoded, otherwise why not.

◆ runRestoreDefaultParametersProcedure()

std::expected< void, std::string > mm::node::runRestoreDefaultParametersProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const RestoreDefaultParametersRequest request,
RestoreDefaultParametersConfig  config = {} 
)

Runs a restore of default parameters (0x1011) as a procedure body.

The counterpart of runStoreParametersProcedure in shape — write the ASCII "load" signature to the sub-entry the group selects, wait, poll until it reads back 1 — and in cancellation, which likewise abandons only the wait.

Destructive: it overwrites the selected group's live values with the device's defaults. Anything unsaved is gone, and anything saved comes back on the next power cycle unless a store follows — some devices apply the restored values only after a reset.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between confirmation polls.
requestWhich group of defaults to restore.
configRetry/timing, as in runStoreParametersProcedure — a testing seam, not a client surface.
Returns
Void once the device confirmed the restore, otherwise why it did not.

◆ runSkippedCyclesProcedure()

std::expected< void, std::string > mm::node::runSkippedCyclesProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const SkippedCyclesRequest request 
)

Reads one control loop's skipped-cycle counter as a procedure body.

The most harmless procedure here: no preparation, no operation mode, no CiA402 state, no brake, and nothing restored — a pure read, safe on a drive that is enabled and moving. It runs from PRE-OP up, needing only an active mailbox.

What it reports is cumulative since the addressed service started, so one run establishes a baseline and a later run establishes a rate. See SomanetDrive::readSkippedCycles.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command so an in-flight read is aborted.
requestWhich control loop to ask.
Returns
Void once the drive reported a counter, otherwise why it did not.

◆ runStoreParametersProcedure()

std::expected< void, std::string > mm::node::runStoreParametersProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
StoreParametersConfig  config = {} 
)

Runs a parameter store (0x1010) as a procedure body.

Writes the ASCII "save" signature to 0x1010:01, waits for the device to begin, then polls until it reads back 1 — the CiA301 "save completed" value. A poll that does not yet confirm is retried within the built-in budget, because a device busy writing to flash may refuse the read outright.

Cancellation abandons the wait, not the store. By the time a run can be cancelled the signature is on the wire and the device is already persisting; stopping only means the master stops waiting for the confirmation, which the step says rather than implying the store was undone.

Needs an active mailbox (PRE-OP or above) and nothing else — no operation mode, no enable, and the shaft does not move.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between confirmation polls.
configRetry/timing. Not part of the procedure's client surface — the catalogue always passes the defaults, since how long a device takes to write flash is a property of the device rather than a caller's choice. It is a parameter so that a test can run the confirmation walk without real waiting, exactly as ProfileDevice::runStoreParameters takes one. config.stop is ignored; stop is the cancellation that applies.
Returns
Void once the device confirmed the store, otherwise why it did not.

◆ runSystemIdentificationProcedure()

std::expected< void, std::string > mm::node::runSystemIdentificationProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const SystemIdentificationRequest request 
)

Configures and optionally arms a system identification run as a procedure body.

Two steps, because the drive has two distinct pieces of state and one is a trigger:

  1. configure-chirp — disarms first, then writes the five settings. Disarming is not housekeeping: the drive starts on the rising edge of the start parameter, so a run left armed by a previous one would never see an edge and would silently not start.
  2. arm — writes the requested trigger. With SystemIdentificationStart::kNone this leaves the drive configured and idle, which is the default.

What it does not do is excite the motor. Arming with kImmediately does — on the next control cycle, if the drive is enabled — and arming with kAfterHrdStreamStart waits for a recording to begin. This procedure needs no operation mode, no CiA402 state and no brake, because configuring needs none of them; whether anything moves is decided by the drive's own state when the trigger fires.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between writes and passed into each command.
requestThe chirp, and whether to arm it.
Returns
Void once every setting was written, otherwise why it stopped.

◆ runTorqueConstantMeasurementProcedure()

std::expected< void, std::string > mm::node::runTorqueConstantMeasurementProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop 
)

Runs torque constant measurement as a procedure body.

Four steps rather than the winding measurements' three: this command's restrictions require a disengaged brake, so the brake is released after Operation Enabled and put back by the restore on every path out, exactly as in runPolePairDetectionProcedure.

The rotor turns for the whole run, which is the longest of these procedures — the drive spins the motor up over about ten seconds and holds it at speed while it measures, because the constant is derived from the back-EMF the motor generates rather than from a torque nobody can measure. The shaft must be free and whatever it drives safe to keep moving.

It measures against the drive's stored motor configuration, and this procedure does not check that. The back-EMF is what is left after the winding impedance is subtracted from the applied voltage, and the drive takes that impedance and the pole pair count from 0x2003:01, :03 and :04. So the useful order is pole pair detection, phase resistance and phase inductance first, their results written into those objects, and this last — which is why it is not part of runOffsetDetectionProcedure: that sequence deliberately stores nothing, so a torque constant measured inside it would be measured against whatever the drive was configured with before.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; checked between steps and passed into the OS command so a running measurement is aborted rather than abandoned.
Returns
Void when the drive reported a torque constant, otherwise why it did not.

◆ runTriggerErrorProcedure()

std::expected< void, std::string > mm::node::runTriggerErrorProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const TriggerErrorRequest request 
)

Provokes a firmware error in a control service as a procedure body.

The only deliberately destructive procedure in the catalogue. It exists because the firmware has the command, and because the behaviour around a stopped control service — what the master sees, what the bus does, what the other devices do — cannot be tested without being able to stop one on purpose. It is a test instrument, not a commissioning step.

Prepares nothing and restores nothing. What it does depends entirely on the error type, and SomanetDrive::triggerError is where that is set out: seven types do nothing at all, four stop the addressed service until the drive is power-cycled, and one raises a resettable fault.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command.
requestWhich service, and which error.
Returns
Void once the command was issued and its outcome established, otherwise why not.

◆ runVelocitySourceProcedure()

std::expected< void, std::string > mm::node::runVelocitySourceProcedure ( Device device,
ProgressReporter reporter,
std::stop_token  stop,
const VelocitySourceRequest request 
)

Chooses the velocity loop's feedback source as a procedure body.

Prepares nothing, restores nothing, and commands no motion — but it is not inert on a moving drive, since the velocity loop's feedback changes under it. See SomanetDrive::setVelocitySource, and note that which source is already active depends on the product rather than on the specification's claim.

Parameters
deviceDevice to run against, borrowed by the manager for this call.
reporterWhere step progress is recorded.
stopCancellation token; passed into the command.
requestWhich source to use.
Returns
Void once the drive accepted the choice, otherwise why it did not.

◆ scalarByteWidth()

size_t mm::node::scalarByteWidth ( uint16_t  dataType)

Width in bytes of a value of dataType, or 0 when it is not a scalar.

The declared width, which is what an SDO transfer carries — not bitLength, which describes the object's slot in the process image and may be narrower.

◆ setCia402OperationMode()

std::expected< Cia402Status, std::string > mm::node::setCia402OperationMode ( DeviceManager deviceManager,
uint16_t  slavePosition,
int8_t  mode,
std::chrono::milliseconds  timeout = std::chrono::milliseconds(200) 
)

Requests an operation mode (0x6060) by its raw value, then reads back the snapshot.

**Raw rather than cia402::OperationMode, because that enum cannot name every mode a drive has**: the negative half of 0x6060 belongs to the vendor, so a SOMANET's diagnostics (-2) or system identification (-4) would be unrepresentable and therefore unrequestable.

The write is confirmed, not assumed. A drive is free to ignore a mode request, and this one does so routinely: SOMANET firmware refuses a change to a non-"dynamic" mode while the drive is in Operation Enabled, and refuses outright any mode its opmode_update does not list — deprecated system identification (-4), for instance. Every one of those refusals is a successful SDO write followed by nothing happening, so this polls 0x6061 up to timeout and reports a mode the drive declined rather than returning a snapshot that quietly contradicts the request. The drive's own reason is usually in 0x603F, and is included when it is.

deviceOperationModes is what answers "does it have this mode" beforehand; this answers "did it take it".

Mode 0 is exempt from the confirmation: it means no mode requested, so there is nothing for the drive to arrive at and a display object that keeps showing the previous mode is not a refusal.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
modeThe 0x6060 value to request.
timeoutHow long to wait for 0x6061 to reflect mode.
Returns
The snapshot once the drive adopted the mode, or an error string if the device is unknown, not a CiA402 drive, the write fails, or the drive declined the mode.

◆ setCia402Target()

std::expected< void, std::string > mm::node::setCia402Target ( DeviceManager deviceManager,
uint16_t  slavePosition,
Cia402TargetKind  kind,
int32_t  setpoint 
)

Writes the one CiA402 cyclic setpoint that matches the active operation mode.

A drive follows a single setpoint at a time — position in PP/CSP, velocity in PV/CSV, torque in PT/CST — so the caller names which kind it is setting (from the selected mode) rather than writing all three. Routes through the live PDO image when the object is mapped and the device is exchanging, else an SDO download (see Device::writeValue). setpoint is the raw value; for kTorque it is per-mille of rated and is narrowed to INTEGER16.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
kindWhich setpoint to write (position / velocity / torque).
setpointThe setpoint value in the object's units.
Returns
Void on success, or an error string if the device is unknown, not a CiA402 drive, or the write fails.

◆ skippedCyclesParameters()

std::vector< ProcedureParameter > mm::node::skippedCyclesParameters ( )

What reading a skipped cycles counter accepts, as its descriptor advertises it.

◆ skippedCyclesSteps()

std::vector< ProgressStep > mm::node::skippedCyclesSteps ( )

The skipped cycles procedure's step template — one step, idle.

◆ somanetProductName()

constexpr std::string_view mm::node::somanetProductName ( uint32_t  productCode)
constexpr

Product name for a raw product code (object 0x1018:02), or empty if the code is not a recognised SOMANET product.

Convenience over SomanetProduct + toString for callers holding a raw code (e.g. Device::productCode()); the empty result lets a caller fall back to another name. The caller is responsible for checking the vendor is kSynapticonVendorId — product codes are only unique within a vendor.

◆ startProcedure()

std::expected< ProcedureSnapshot, ProcedureError > mm::node::startProcedure ( DeviceManager deviceManager,
ProcedureManager procedureManager,
uint16_t  devicePosition,
std::string_view  name,
const nlohmann::json &  request 
)

Starts name on devicePosition with request as its parameters.

Returns
The initial snapshot (status running, runCount already bumped), or why it could not start — any of the four ProcedureError kinds.

◆ stepsFrom()

std::vector< ProgressStep > mm::node::stepsFrom ( std::initializer_list< std::string_view >  ids)

A procedure's step template: the given ids, in order, all idle.

Every procedure declares its steps this way, which is why it lives here rather than beside any one family of them.

◆ storeParametersSteps()

std::vector< ProgressStep > mm::node::storeParametersSteps ( )

Store parameters' step template — one step, idle.

◆ stringArrayParameter()

ProcedureParameter mm::node::stringArrayParameter ( std::string  name,
std::string  title,
std::string  description,
nlohmann::json  defaultValue 
)

A parameter taking a list of strings, which the client renders as an editable list.

Parameters
defaultValueA JSON array used when the request omits the parameter; pass nullptr to make it required. An empty array is a meaningful default and not the same as no default — "skip nothing" is a real answer — so a caller that wants the parameter optional-with-nothing-selected passes nlohmann::json::array().

◆ stringParameter()

ProcedureParameter mm::node::stringParameter ( std::string  name,
std::string  title,
std::string  description,
nlohmann::json  defaultValue 
)

A free-text parameter. defaultValue as in integerParameter.

◆ syncStateName()

std::string_view mm::node::syncStateName ( SyncState  state)

Returns the lowercase string form of state ("unknown" etc.).

◆ systemIdentificationParameters()

std::vector< ProcedureParameter > mm::node::systemIdentificationParameters ( )

What system identification accepts, as its descriptor advertises it.

◆ systemIdentificationSteps()

std::vector< ProgressStep > mm::node::systemIdentificationSteps ( )

The system identification procedure's step template — configure, then arm.

◆ to_json() [1/50]

void mm::node::to_json ( nlohmann::json &  j,
const BrakeState state 
)

◆ to_json() [2/50]

void mm::node::to_json ( nlohmann::json &  j,
const Cia402Status s 
)

Serialises a Cia402Status. Emits state/modeName as human-readable strings alongside the numeric statusword, controlword, and modeOfOperation.

◆ to_json() [3/50]

void mm::node::to_json ( nlohmann::json &  j,
const CommutationOffsetResult result 
)

◆ to_json() [4/50]

void mm::node::to_json ( nlohmann::json &  j,
const DcSyncInfo info 
)

Serialises a DcSyncInfo to JSON.

◆ to_json() [5/50]

void mm::node::to_json ( nlohmann::json &  j,
const Device d 
)

Serialises a Device to JSON.

Produces an object with keys slavePosition, name, productName, vendorId, productCode, revisionNumber, serialNumber, and isCia402. Participates in nlohmann ADL so that nlohmann::json(device) and std::vector<Device> conversions work automatically.

Parameters
jOutput JSON value.
dDevice to serialise.

◆ to_json() [6/50]

void mm::node::to_json ( nlohmann::json &  j,
const DeviceDiagnosticsInfo info 
)

Serialises a DeviceDiagnosticsInfo (and its nested per-port counters) to JSON.

◆ to_json() [7/50]

void mm::node::to_json ( nlohmann::json &  j,
const DeviceFile file 
)

◆ to_json() [8/50]

void mm::node::to_json ( nlohmann::json &  j,
const DeviceManager dm 
)

Serialises all devices in a DeviceManager to a JSON array.

Produces a JSON array where each element is the serialised form of a Device (see to_json(nlohmann::json&, const Device&)), in bus order. Participates in nlohmann ADL so that nlohmann::json(deviceManager) works.

Parameters
jOutput JSON value.
dmDeviceManager whose device list to serialise.

◆ to_json() [9/50]

void mm::node::to_json ( nlohmann::json &  j,
const DeviceParameter p 
)

Serialises a DeviceParameter to JSON.

Produces an object with keys index, subindex, name, objectCode, dataType, bitLength, access, and value.

◆ to_json() [10/50]

void mm::node::to_json ( nlohmann::json &  j,
const DeviceStateInfo info 
)

Serialises a DeviceStateInfo to JSON.

◆ to_json() [11/50]

void mm::node::to_json ( nlohmann::json &  j,
const EncoderRegisterResult result 
)

◆ to_json() [12/50]

void mm::node::to_json ( nlohmann::json &  j,
const FirmwareCompatibility compatibility 
)

◆ to_json() [13/50]

void mm::node::to_json ( nlohmann::json &  j,
const FirmwareLatencyResult result 
)

◆ to_json() [14/50]

void mm::node::to_json ( nlohmann::json &  j,
const FirmwarePackageName name 
)

Serialises a decoded package name — the body of GET /api/firmware-package-name.

The four decoded-descriptor fields are omitted rather than sent as null when the descriptor is not the numeric kind, so "this name carries no product id" is an absent key rather than a value a client has to null-check.

◆ to_json() [15/50]

void mm::node::to_json ( nlohmann::json &  j,
const FullFirmwareDescriptors descriptors 
)

Serialises the descriptors and a verdict.

assembly is omitted rather than null when the device is not part of one, matching how the hardware description itself is serialised.

◆ to_json() [16/50]

void mm::node::to_json ( nlohmann::json &  j,
const HardwareComponent component 
)

Serialises a component, a product and a whole description.

Field names are the file's own, so a serialised description reads as the file it came from, with buildDescriptor added to each product because it is the part a client wants and would otherwise re-derive. Empty optional strings are still emitted — the shape of a product should not change with whether a serial number was recorded.

◆ to_json() [17/50]

void mm::node::to_json ( nlohmann::json &  j,
const HardwareDescription description 
)

◆ to_json() [18/50]

void mm::node::to_json ( nlohmann::json &  j,
const HardwareProduct product 
)

◆ to_json() [19/50]

void mm::node::to_json ( nlohmann::json &  j,
const HrdRecording recording 
)

◆ to_json() [20/50]

void mm::node::to_json ( nlohmann::json &  j,
const IntegroVariant variant 
)

Serialises a parsed file.

signature and chipId become lowercase hex strings rather than arrays of numbers, the operation mode carries its decoded name beside its value, and each option code is expanded into its catalogue entry — with the entry's fields absent for a code the catalogue does not name, so "we do not know what this is" is missing keys rather than the string "unknown".

◆ to_json() [21/50]

void mm::node::to_json ( nlohmann::json &  j,
const IntegroVariantOption option 
)

Serialises one catalogue entry — the body of GET /api/integro-variant/options.

◆ to_json() [22/50]

void mm::node::to_json ( nlohmann::json &  j,
const KueblerRegisterResult result 
)

◆ to_json() [23/50]

void mm::node::to_json ( nlohmann::json &  j,
const MonitoredParameter p 
)

Serialises a MonitoredParameter to JSON: {devicePosition, index, subindex}.

◆ to_json() [24/50]

void mm::node::to_json ( nlohmann::json &  j,
const Monitoring m 
)

Serialises a Monitoring to JSON: {topic, name?, interval, parameters}.

name is omitted when unset; interval is emitted as an integer count of milliseconds.

◆ to_json() [25/50]

void mm::node::to_json ( nlohmann::json &  j,
const MotorPhaseOrderResult result 
)

◆ to_json() [26/50]

void mm::node::to_json ( nlohmann::json &  j,
const ObjectDictionaryValue entry 
)

◆ to_json() [27/50]

void mm::node::to_json ( nlohmann::json &  j,
const ObjectDictionaryValues values 
)

◆ to_json() [28/50]

void mm::node::to_json ( nlohmann::json &  j,
const OpenPhaseResult result 
)

◆ to_json() [29/50]

void mm::node::to_json ( nlohmann::json &  j,
const OperationModes modes 
)

◆ to_json() [30/50]

void mm::node::to_json ( nlohmann::json &  j,
const OsCommandResult result 
)

◆ to_json() [31/50]

void mm::node::to_json ( nlohmann::json &  j,
const OutputStageResult result 
)

Serialises an OutputStageResult to JSON.

◆ to_json() [32/50]

void mm::node::to_json ( nlohmann::json &  j,
const ParameterCache::CacheEntry e 
)

Serialises a CacheEntry to JSON (keys: vendorId, productCode, revisionNumber, parameterCount, sizeBytes). Participates in nlohmann ADL.

◆ to_json() [33/50]

void mm::node::to_json ( nlohmann::json &  j,
const ParameterOption option 
)

◆ to_json() [34/50]

void mm::node::to_json ( nlohmann::json &  j,
const PdoMapping m 
)

Serialises a device's grouped mapping: outputs / inputs object arrays. The response shape of the PDO-mapping routes (each entry carries its derived bitOffset).

◆ to_json() [35/50]

void mm::node::to_json ( nlohmann::json &  j,
const PdoMappingEntry e 
)

Serialises a single entry: index, subindex, bitLength, bitOffset.

◆ to_json() [36/50]

void mm::node::to_json ( nlohmann::json &  j,
const PdoMappingObject o 
)

Serialises one mapping object: pdoIndex and its ordered entries.

◆ to_json() [37/50]

void mm::node::to_json ( nlohmann::json &  j,
const PhaseInductanceResult result 
)

◆ to_json() [38/50]

void mm::node::to_json ( nlohmann::json &  j,
const PhaseResistanceResult result 
)

◆ to_json() [39/50]

void mm::node::to_json ( nlohmann::json &  j,
const PolePairResult result 
)

◆ to_json() [40/50]

void mm::node::to_json ( nlohmann::json &  j,
const ProcedureDescriptor descriptor 
)

◆ to_json() [41/50]

void mm::node::to_json ( nlohmann::json &  j,
const ProcedureListing listing 
)

◆ to_json() [42/50]

void mm::node::to_json ( nlohmann::json &  j,
const ProcedureParameter parameter 
)

◆ to_json() [43/50]

void mm::node::to_json ( nlohmann::json &  j,
const ProcedureSnapshot snapshot 
)

◆ to_json() [44/50]

void mm::node::to_json ( nlohmann::json &  j,
const ProcessImageInfo info 
)

Serialises a ProcessImageInfo to JSON.

◆ to_json() [45/50]

void mm::node::to_json ( nlohmann::json &  j,
const ProcessImageObjectInfo obj 
)

Serialises a ProcessImageObjectInfo to JSON.

◆ to_json() [46/50]

void mm::node::to_json ( nlohmann::json &  j,
const ProgressStep step 
)

◆ to_json() [47/50]

void mm::node::to_json ( nlohmann::json &  j,
const SkippedCyclesResult result 
)

◆ to_json() [48/50]

void mm::node::to_json ( nlohmann::json &  j,
const SlaveConfigInfo info 
)

Serialises a SlaveConfigInfo (and its nested SM/FMMU/mailbox/DC) to JSON.

◆ to_json() [49/50]

void mm::node::to_json ( nlohmann::json &  j,
const TorqueConstantResult result 
)

◆ to_json() [50/50]

void mm::node::to_json ( nlohmann::json &  j,
const TriggerErrorResult result 
)

◆ toCsv()

std::string mm::node::toCsv ( const HrdRecording recording)

Renders a recording as CSV: one header row of column names, then one row per sample.

The second representation of the same recording, for the spreadsheet-and-script half of the audience — a full recording is ten thousand rows, which is a file to open rather than JSON to read. Beside to_json rather than in the HTTP layer, so the two renderings of one type stay together.

Every row ends in a newline, the header included, so appending or concatenating cannot join two records onto one line.

◆ torqueConstantMeasurementSteps()

std::vector< ProgressStep > mm::node::torqueConstantMeasurementSteps ( )

Torque constant measurement's step template — prepare, release the brake, measure, restore.

◆ toString() [1/9]

constexpr std::string_view mm::node::toString ( FirmwareLatencyAction  action)
constexpr

Name of a firmware latency action (for JSON). Never returns nullptr.

◆ toString() [2/9]

std::string_view mm::node::toString ( FirmwareMatch  match)

What a match is called, for a message or a JSON body: "none", "assembly", "device".

◆ toString() [3/9]

constexpr std::string_view mm::node::toString ( FsBufferTransfer  transfer)
constexpr

Name of an fs-buffer direction, as a request and a response spell it.

◆ toString() [4/9]

constexpr std::string_view mm::node::toString ( ParameterType  type)
constexpr

Human-readable name of a parameter type (for JSON). Never returns nullptr.

◆ toString() [5/9]

constexpr std::string_view mm::node::toString ( ProcedureStatus  status)
constexpr

Human-readable name of a procedure status (for logging / JSON). Never nullptr.

◆ toString() [6/9]

constexpr std::string_view mm::node::toString ( ProgressStatus  status)
constexpr

Human-readable name of a step status (for logging / JSON). Never returns nullptr.

◆ toString() [7/9]

constexpr std::string_view mm::node::toString ( RestoreGroup  group)
constexpr

The token naming group — the inverse of parseRestoreGroup, and the form the group takes on the wire. Never returns nullptr.

◆ toString() [8/9]

constexpr std::string_view mm::node::toString ( SomanetProduct  product)
constexpr

Human-readable name of a known SOMANET product (for logging / JSON). Returns "Unknown" for a product code not in SomanetProduct.

The strings match the device <Type> name in Synapticon's ESI (EtherCAT Slave Information), where "SOMANET" is part of the product name.

◆ toString() [9/9]

std::string_view mm::node::toString ( VariantOperationMode  mode)

The mode's name, or "unknown" for a value no firmware release defines.

◆ transitionToCia402State()

std::expected< Cia402Status, std::string > mm::node::transitionToCia402State ( DeviceManager deviceManager,
uint16_t  slavePosition,
cia402::State  target,
std::chrono::milliseconds  timeout = std::chrono::milliseconds(2000) 
)

Brings a drive to target, walking whatever transitions that takes, then reads back the resulting snapshot.

The state-oriented counterpart of runCia402Command: a caller names a destination rather than the edges to get there, and the master issues them one at a time, re-reading the drive between each (Cia402Drive::transitionToState). Multi-hop paths — Switch On Disabled to Operation Enabled, Quick Stop Active back down to Ready To Switch On — are ordinary, as is starting from Fault, which begins with a reset.

**The quick-stop override is on here, and that is the difference from runCia402Command's kEnable.** Asking for Operation Enabled while the drive sits in Quick Stop Active is an explicit instruction to leave that stop, so transition 16 is used; the same request through kEnable — which procedures make to prepare a drive, not to override anybody — is refused.

The drive must be exchanging process data for any of this to progress: the statusword has to update between polls, and the firmware refuses Operation Enabled outright unless master communication is live.

Parameters
deviceManagerOwner of the device set; lends locked access for the call.
slavePosition1-based bus position of the target device.
targetWhere to bring the drive. Must be cia402::isCommandableState.
timeoutMaximum time to spend walking.
Returns
The snapshot after arriving, or an error string if the device is unknown, not a CiA402 drive, the target is not commandable, a fault will not clear, or the walk times out.

◆ triggerErrorParameters()

std::vector< ProcedureParameter > mm::node::triggerErrorParameters ( )

What provoking a firmware error accepts, as its descriptor advertises it.

◆ triggerErrorSteps()

std::vector< ProgressStep > mm::node::triggerErrorSteps ( )

The trigger-error procedure's step template — one step, idle.

◆ unpackLeBits()

void mm::node::unpackLeBits ( uint64_t  bits,
std::span< uint8_t >  out 
)

Unpacks bits into out, little-endian. The inverse of packLeBits.

◆ unpackMappingEntry()

PdoMappingEntry mm::node::unpackMappingEntry ( uint32_t  packed)
inline

Unpacks a 32-bit CoE mapping word into an entry — the inverse of packMappingEntry.

The returned entry's bitOffset is left at its default; the reader fills it from the running offset. An index of 0x0000 denotes an alignment gap (no bound object).

◆ variantFieldbusProtocol()

std::optional< uint16_t > mm::node::variantFieldbusProtocol ( const IntegroVariant variant)

The selected fieldbus protocol, for the tail of a full firmware descriptor (specification §3.4.2.1).

One fieldbus is selected on a production device. A development device may have several selected, so that one unit can be tested on more than one protocol; EtherCAT is the one to use when it is among them.

Only Integro devices reach this. Node and Circulo are EtherCAT-only with every feature enabled, and carry no variant file.

Parameters
variantA parsed file.
Returns
The code, or nothing when the file selects no fieldbus.

◆ velocitySourceParameters()

std::vector< ProcedureParameter > mm::node::velocitySourceParameters ( )

What choosing the velocity source accepts, as its descriptor advertises it.

◆ velocitySourceSteps()

std::vector< ProgressStep > mm::node::velocitySourceSteps ( )

The velocity-source procedure's step template — one step, idle.

◆ writeProcessDataDump()

std::expected< uint64_t, std::string > mm::node::writeProcessDataDump ( std::ostream &  out,
const DumpHeader header,
uint64_t  startSeq,
uint64_t  endSeq,
const DumpRecordReader read 
)

Serialises the frozen span [startSeq, endSeq) to out as a .mmpd dump.

Streams each row directly from read (no whole-span buffer), padding/truncating its input/output regions to the header sizes for a fixed stride. A record read cannot return (lapped while the producer is still running, or a torn read) is skipped — every row carries its own sequence, so a gap is self-describing and needs no marker; at a seconds-deep ring versus a sub-second bulk write this never actually happens. rowCount is patched at kDumpRowCountOffset once the real count is known, so out must be seekable (a file or string stream).

Returns
The number of rows written, or an error string if a stream write/seek failed.

Variable Documentation

◆ kBissIgnoreByte

constexpr size_t mm::node::kBissIgnoreByte = 1
constexpr

◆ kBissIgnoreEncoderShift

constexpr unsigned mm::node::kBissIgnoreEncoderShift = 1
constexpr

◆ kBissIgnoreTrigger

constexpr uint8_t mm::node::kBissIgnoreTrigger = 0x01
constexpr

◆ kCommutationOffsetMeasurementProcedure

constexpr std::string_view mm::node::kCommutationOffsetMeasurementProcedure
inlineconstexpr
Initial value:
=
"commutation-offset-measurement"

Procedure name for commutation offset measurement, as it appears in its URL and its snapshot key.

◆ kCommutationOffsetMeasurementStep

constexpr std::string_view mm::node::kCommutationOffsetMeasurementStep
inlineconstexpr
Initial value:
=
"commutation-offset-measurement"

The step commutation offset measurement's own measurement reports against.

◆ kDefaultSkippedFirmwareFiles

constexpr std::array<std::string_view, 2> mm::node::kDefaultSkippedFirmwareFiles
inlineconstexpr
Initial value:
= {
"SOMANET_CiA_402.xml.zip",
"stack_image.svg.zip",
}

The entries an install skips unless the request names a different set.

Both are descriptive extras rather than firmware: SOMANET_CiA_402.xml.zip is the ESI, which a commissioning tool reads from the package itself rather than from the drive, and stack_image.svg.zip is a picture of the hardware. Writing them costs a slow FoE transfer each (the ESI alone takes ~17 s to erase before it can be rewritten) and consumes drive flash to store something nothing on the drive reads. They are skipped by default and un-skippable only deliberately, by sending a request that omits them from the list.

◆ kDumpFormatVersion

constexpr uint16_t mm::node::kDumpFormatVersion = 1
inlineconstexpr

Current dump format version. A reader rejects an unknown major shape; bump on layout changes so old files stay identifiable.

◆ kDumpMagic

constexpr std::array<char, 4> mm::node::kDumpMagic = {'M', 'M', 'P', 'D'}
inlineconstexpr

Magic at the very start of every dump file.

◆ kDumpRowCountOffset

constexpr std::streamoff mm::node::kDumpRowCountOffset = 16
inlineconstexpr

Byte offset of the rowCount field within the fixed prefix. The writer streams rows first, then seeks here to patch the final count — so the stream must be seekable.

◆ kEncoderRegisterProcedure

constexpr std::string_view mm::node::kEncoderRegisterProcedure = "encoder-register-communication"
inlineconstexpr

Procedure name for encoder register communication, as it appears in its URL and its snapshot key.

◆ kEncoderRegisterStep

constexpr std::string_view mm::node::kEncoderRegisterStep = "register-access"
inlineconstexpr

The single step encoder register communication reports against.

◆ kFirmwareInstallationProcedure

constexpr std::string_view mm::node::kFirmwareInstallationProcedure = "firmware-installation"
inlineconstexpr

Procedure name, as it appears in its URL and its snapshot key.

◆ kFirmwareLatencyActionByte

constexpr size_t mm::node::kFirmwareLatencyActionByte = 1
constexpr

◆ kFirmwareLatencyConfiguredOffset

constexpr size_t mm::node::kFirmwareLatencyConfiguredOffset = 3
constexpr

◆ kFirmwareLatencyIndexByte

constexpr size_t mm::node::kFirmwareLatencyIndexByte = 2
constexpr

◆ kFirmwareLatencyMaximumOffset

constexpr size_t mm::node::kFirmwareLatencyMaximumOffset = 0
constexpr

◆ kFirmwareLatencyObserveStep

constexpr std::string_view mm::node::kFirmwareLatencyObserveStep = "observe"
inlineconstexpr

The step that lets the drive run while the measurement collects. Occupies the whole requested duration, and only FirmwareLatencyAction::kMeasure performs it.

◆ kFirmwareLatencyProcedure

constexpr std::string_view mm::node::kFirmwareLatencyProcedure = "firmware-latency-measurement"
inlineconstexpr

Procedure name for measuring a firmware latency, as it appears in its URL and its snapshot key.

◆ kFirmwareLatencyReadStep

constexpr std::string_view mm::node::kFirmwareLatencyReadStep = "read-maximum"
inlineconstexpr

The step that reads and clears the recorded maximum.

◆ kFirmwareLatencyStartStep

constexpr std::string_view mm::node::kFirmwareLatencyStartStep = "start-measurement"
inlineconstexpr

The step that starts a measurement, and clears whatever the latency recorded.

◆ kFirmwareLatencyStopStep

constexpr std::string_view mm::node::kFirmwareLatencyStopStep = "stop-measurements"
inlineconstexpr

The step that stops both measurements.

◆ kFirmwareLatencyValueBytes

constexpr size_t mm::node::kFirmwareLatencyValueBytes = 3
constexpr

◆ kFirmwareServiceByte

constexpr size_t mm::node::kFirmwareServiceByte = 1
constexpr

◆ kFsBufferFilename

constexpr std::string_view mm::node::kFsBufferFilename = "fs-buffer"
inlineconstexpr

The FoE filename that moves bulk data for an OS command.

The firmware compares the requested filename against this exact string. On a match it does not open a file at all: it connects the transfer to a block of memory that an OS command writes to or reads from. Any other name, including one that only starts with these characters, is read as an ordinary file.

◆ kGetAndClearMaximumLatency

constexpr uint8_t mm::node::kGetAndClearMaximumLatency = 1
constexpr

◆ kHrdConfigureStep

constexpr std::string_view mm::node::kHrdConfigureStep = "configure-stream"
inlineconstexpr

The step that arms the recording — chooses the signal and the duration, and clears the files the last recording left behind.

◆ kHrdRecordStep

constexpr std::string_view mm::node::kHrdRecordStep = "record"
inlineconstexpr

The step that records. Occupies the whole configured duration.

◆ kHrdStreamingProcedure

constexpr std::string_view mm::node::kHrdStreamingProcedure = "hrd-streaming"
inlineconstexpr

Procedure name for recording a high resolution data stream, as it appears in its URL and its snapshot key.

◆ kIcMuCalibrationModeProcedure

constexpr std::string_view mm::node::kIcMuCalibrationModeProcedure = "ic-mu-calibration-mode"
inlineconstexpr

Procedure name for setting an iC-MU calibration mode, as it appears in its URL and its snapshot key.

◆ kIcMuCalibrationModeStep

constexpr std::string_view mm::node::kIcMuCalibrationModeStep = "set-mode"
inlineconstexpr

The single step setting an iC-MU calibration mode reports against.

◆ kIgnoreBissStatusBitsProcedure

constexpr std::string_view mm::node::kIgnoreBissStatusBitsProcedure = "ignore-biss-status-bits"
inlineconstexpr

Procedure name for ignoring a BiSS encoder's status bits, as it appears in its URL and its snapshot key.

◆ kIgnoreBissStatusBitsStep

constexpr std::string_view mm::node::kIgnoreBissStatusBitsStep = "set-ignore"
inlineconstexpr

The single step ignoring BiSS status bits reports against.

◆ kKueblerAddressByte

constexpr size_t mm::node::kKueblerAddressByte = 2
constexpr

◆ kKueblerDirectionByte

constexpr size_t mm::node::kKueblerDirectionByte = 1
constexpr

◆ kKueblerLengthByte

constexpr size_t mm::node::kKueblerLengthByte = 3
constexpr

◆ kKueblerRegisterProcedure

constexpr std::string_view mm::node::kKueblerRegisterProcedure = "kuebler-register-communication"
inlineconstexpr

Procedure name for a Kübler encoder register access, as it appears in its URL and its snapshot key.

◆ kKueblerRegisterStep

constexpr std::string_view mm::node::kKueblerRegisterStep = "register-access"
inlineconstexpr

The single step a Kübler register access reports against.

◆ kKueblerValueLsbByte

constexpr size_t mm::node::kKueblerValueLsbByte = 4
constexpr

◆ kLatencyTickNanoseconds

constexpr uint32_t mm::node::kLatencyTickNanoseconds = 10
constexpr

◆ kMaxVariantOptions

constexpr uint16_t mm::node::kMaxVariantOptions = 32
inlineconstexpr

The most options a file may carry (firmware MAX_VARIANTS_COUNT).

Enforced rather than documented: firmware refuses a file claiming more with OPTIONS_STATUS_TOO_MANY_OPTIONS, so a count above this is a file the drive itself would not accept.

◆ kMotorPhaseOrderDetectionProcedure

constexpr std::string_view mm::node::kMotorPhaseOrderDetectionProcedure
inlineconstexpr
Initial value:
=
"motor-phase-order-detection"

Procedure name for motor phase order detection, as it appears in its URL and its snapshot key.

◆ kMotorPhaseOrderDetectionStep

constexpr std::string_view mm::node::kMotorPhaseOrderDetectionStep = "motor-phase-order-detection"
inlineconstexpr

The step motor phase order detection's own measurement reports against.

◆ kNotificationTopic

constexpr std::string_view mm::node::kNotificationTopic = "notifications"
inlineconstexpr

The one topic every notification is published to.

One topic rather than one per source, so a client subscribes once and keeps receiving events added after it was written. See NotificationBus.

◆ kObjectsOutsideOdValues

constexpr std::array<uint32_t, 1> mm::node::kObjectsOutsideOdValues
inlineconstexpr
Initial value:
{
makeParameterKey(0x10F8, 0x00),
}
constexpr uint32_t makeParameterKey(uint16_t index, uint8_t subindex)
Packs an object dictionary index and subindex into a single 32-bit key.
Definition device_parameter.h:38

The entries a SOMANET drive answers for over CoE that OS command 21 does not carry.

The command sends one array, and the CoE dictionary is bigger than that array. OS command 21 streams the firmware's od_values, which holds the application object dictionary. An Integro also answers for 0x10F8, the standard Timestamp Object, because the EtherCAT stack in its communication processor serves that one rather than the application does. It has no slot in od_values, so its eight bytes are never sent, and a decode that expected them shifts every value after it.

This is a list because the wire offers no rule. Nothing in the SDO Info answer tells the two apart: 0x10F8 comes back as an ordinary VAR with ordinary access flags. What keeps the list honest is the check that was already there — the widths must add up to exactly the bytes the drive sent — so a list that is wrong fails the transfer instead of quietly shifting it.

A device that does not hold one of these loses nothing: an entry is skipped only when the device's own dictionary has it. A SOMANET Node has no 0x10F8.

Packed keys rather than a struct, so this needs no type of its own — makeParameterKey is what the rest of the code already compares an index and a subindex with.

◆ kOffsetDetectionProcedure

constexpr std::string_view mm::node::kOffsetDetectionProcedure = "offset-detection"
inlineconstexpr

Procedure name for the whole commissioning sequence, as it appears in its URL and its snapshot key.

Offset detection is what this sequence has always been called, and the name people will look for. Not to be confused with kCommutationOffsetMeasurementProcedure, which is the last command of this sequence on its own.

◆ kOpenPhaseDetectionProcedure

constexpr std::string_view mm::node::kOpenPhaseDetectionProcedure = "open-phase-detection"
inlineconstexpr

Procedure name for open phase detection, as it appears in its URL and its snapshot key.

◆ kOpenPhaseDetectionStep

constexpr std::string_view mm::node::kOpenPhaseDetectionStep = "open-phase-detection"
inlineconstexpr

The step open phase detection's own measurement reports against.

◆ kOsCommandProcedure

constexpr std::string_view mm::node::kOsCommandProcedure = "os-command"
inlineconstexpr

Procedure name for the raw OS command, as it appears in its URL and its snapshot key.

◆ kOsCommandSize

constexpr size_t mm::node::kOsCommandSize = 8
inlineconstexpr

Byte length of the OS command and response octet strings (0x1023:01 / 0x1023:03). Manufacturer-specific — the firmware specification allows it to grow, so read it from here rather than writing 8 at a call site.

◆ kOsCommandStep

constexpr std::string_view mm::node::kOsCommandStep = "command"
inlineconstexpr

The single step the OS command procedure reports against.

◆ kPhaseInductanceMeasurementProcedure

constexpr std::string_view mm::node::kPhaseInductanceMeasurementProcedure
inlineconstexpr
Initial value:
=
"phase-inductance-measurement"

Procedure name for phase inductance measurement, as it appears in its URL and its snapshot key.

◆ kPhaseInductanceMeasurementStep

constexpr std::string_view mm::node::kPhaseInductanceMeasurementStep = "phase-inductance-measurement"
inlineconstexpr

The step phase inductance measurement's own measurement reports against.

◆ kPhaseResistanceMeasurementProcedure

constexpr std::string_view mm::node::kPhaseResistanceMeasurementProcedure
inlineconstexpr
Initial value:
=
"phase-resistance-measurement"

Procedure name for phase resistance measurement, as it appears in its URL and its snapshot key.

◆ kPhaseResistanceMeasurementStep

constexpr std::string_view mm::node::kPhaseResistanceMeasurementStep = "phase-resistance-measurement"
inlineconstexpr

The step phase resistance measurement's own measurement reports against.

◆ kPolePairDetectionProcedure

constexpr std::string_view mm::node::kPolePairDetectionProcedure = "pole-pair-detection"
inlineconstexpr

Procedure name for pole pair detection, as it appears in its URL and its snapshot key.

◆ kPolePairDetectionStep

constexpr std::string_view mm::node::kPolePairDetectionStep = "pole-pair-detection"
inlineconstexpr

The step pole pair detection's own measurement reports against.

◆ kPrepareStep

constexpr std::string_view mm::node::kPrepareStep = "prepare"
inlineconstexpr

The step ids shared by every procedure that prepares a drive, measures, and puts it back.

The preparation and its undoing are the same work in each of them — SOMANET's diagnostics operation mode, CiA402 Operation Enabled, and for some commands a released brake — so they carry the same ids everywhere rather than a near-identical set named per procedure, and a client labels them once. What differs is the measurement step in between, which each procedure names itself.

They are steps rather than hidden setup because each can fail on real hardware — a drive that will not enable, a brake that will not restore — and a user staring at a stalled procedure needs to see which part stalled. kReleaseBrakeStep appears only in the procedures whose command requires the brake released; the others leave it exactly as they found it.

◆ kReadObjectDictionaryProcedure

constexpr std::string_view mm::node::kReadObjectDictionaryProcedure = "read-object-dictionary"
inlineconstexpr

Procedure name for reading the whole object dictionary, as it appears in its URL and its snapshot key.

◆ kReadObjectDictionaryStep

constexpr std::string_view mm::node::kReadObjectDictionaryStep = "read-dictionary"
inlineconstexpr

The single step reading the whole object dictionary reports against.

◆ kReleaseBrakeStep

constexpr std::string_view mm::node::kReleaseBrakeStep = "release-brake"
inlineconstexpr

◆ kRestoreDefaultParametersProcedure

constexpr std::string_view mm::node::kRestoreDefaultParametersProcedure = "restore-default-parameters"
inlineconstexpr

Procedure name for restoring default parameters, as it appears in its URL and its snapshot key.

◆ kRestoreDefaultParametersStep

constexpr std::string_view mm::node::kRestoreDefaultParametersStep = "restore"
inlineconstexpr

The single step restoring default parameters reports against.

◆ kRestoreStep

constexpr std::string_view mm::node::kRestoreStep = "restore"
inlineconstexpr

◆ kSetBrakeStep

constexpr std::string_view mm::node::kSetBrakeStep = "set-brake"
inlineconstexpr

The step that puts the brake where the configured method needs it.

Its own id rather than kReleaseBrakeStep, because the commissioning sequence may engage the brake there instead of releasing it: it released the brake for motor phase order detection, and the stationary offset method that follows cannot hold the load, so the release has to be undone. A step called "release-brake" that sometimes engages would be a lie in the step array.

◆ kSkippedCyclesProcedure

constexpr std::string_view mm::node::kSkippedCyclesProcedure = "skipped-cycles-counter"
inlineconstexpr

Procedure name for reading a skipped cycles counter, as it appears in its URL and its snapshot key.

◆ kSkippedCyclesStep

constexpr std::string_view mm::node::kSkippedCyclesStep = "read-counter"
inlineconstexpr

The single step reading a skipped cycles counter reports against.

◆ kStartLatencyMeasurement

constexpr uint8_t mm::node::kStartLatencyMeasurement = 0
constexpr

◆ kStopLatencyMeasurements

constexpr uint8_t mm::node::kStopLatencyMeasurements = 2
constexpr

◆ kStoreParametersProcedure

constexpr std::string_view mm::node::kStoreParametersProcedure = "store-parameters"
inlineconstexpr

Procedure name for storing parameters, as it appears in its URL and its snapshot key.

◆ kStoreParametersStep

constexpr std::string_view mm::node::kStoreParametersStep = "store"
inlineconstexpr

The single step storing parameters reports against.

◆ kSynapticonVendorId

constexpr uint32_t mm::node::kSynapticonVendorId = 0x000022D2
inlineconstexpr

Synapticon's EtherCAT Vendor ID (object 0x1018:01) — the discriminator for a SOMANET drive and the single source of truth for the vendor check.

Kept in its own header so both the profile-view chain (SomanetDrive) and the object-dictionary cache (ParameterCache) can share this definition without either depending on the other's headers.

◆ kSystemIdArmStep

constexpr std::string_view mm::node::kSystemIdArmStep = "arm"
inlineconstexpr

The step that arms the run — or disarms it.

◆ kSystemIdConfigureStep

constexpr std::string_view mm::node::kSystemIdConfigureStep = "configure-chirp"
inlineconstexpr

The step that writes the chirp's five settings.

◆ kSystemIdentificationProcedure

constexpr std::string_view mm::node::kSystemIdentificationProcedure = "system-identification"
inlineconstexpr

Procedure name for configuring a system identification run, as it appears in its URL and its snapshot key.

◆ kSystemIdParameterByte

constexpr size_t mm::node::kSystemIdParameterByte = 1
constexpr

◆ kSystemIdValueMsbByte

constexpr size_t mm::node::kSystemIdValueMsbByte = 2
constexpr

◆ kTorqueConstantMeasurementProcedure

constexpr std::string_view mm::node::kTorqueConstantMeasurementProcedure
inlineconstexpr
Initial value:
=
"torque-constant-measurement"

Procedure name for torque constant measurement, as it appears in its URL and its snapshot key.

◆ kTorqueConstantMeasurementStep

constexpr std::string_view mm::node::kTorqueConstantMeasurementStep = "torque-constant-measurement"
inlineconstexpr

The step torque constant measurement's own measurement reports against.

◆ kTriggerErrorProcedure

constexpr std::string_view mm::node::kTriggerErrorProcedure = "trigger-error"
inlineconstexpr

Procedure name for provoking a firmware error, as it appears in its URL and its snapshot key.

◆ kTriggerErrorServiceByte

constexpr size_t mm::node::kTriggerErrorServiceByte = 1
constexpr

◆ kTriggerErrorStep

constexpr std::string_view mm::node::kTriggerErrorStep = "trigger"
inlineconstexpr

The single step provoking a firmware error reports against.

◆ kTriggerErrorTypeByte

constexpr size_t mm::node::kTriggerErrorTypeByte = 2
constexpr

◆ kVelocitySourceByte

constexpr size_t mm::node::kVelocitySourceByte = 1
constexpr

◆ kVelocitySourceProcedure

constexpr std::string_view mm::node::kVelocitySourceProcedure = "velocity-source"
inlineconstexpr

Procedure name for choosing the velocity feedback source, as it appears in its URL and its snapshot key.

◆ kVelocitySourceStep

constexpr std::string_view mm::node::kVelocitySourceStep = "set-source"
inlineconstexpr

The single step choosing the velocity source reports against.