Motion Master 6.0.0-alpha.50
Next-generation motion control software
Loading...
Searching...
No Matches
mm::node::Device Class Reference

Represents a single node on the fieldbus. More...

#include <device.h>

Public Member Functions

 Device (uint16_t slavePosition, mm::comm::FieldbusDriver &driver, ProcessData *processData=nullptr, const ParameterCache *parameterCache=nullptr)
 Constructs a device, reading identity from the driver at slavePosition.
 
uint16_t slavePosition () const
 Returns the 1-based position of this node on the fieldbus.
 
const std::string & name () const
 Human-readable node name from SII EEPROM.
 
uint32_t vendorId () const
 Vendor ID from EEPROM.
 
uint32_t productCode () const
 Product code from EEPROM.
 
uint32_t revisionNumber () const
 Revision number from EEPROM.
 
uint32_t serialNumber () const
 Serial number from EEPROM.
 
bool mailboxActive () const
 Whether the device's CoE/SDO mailbox is currently active (AL state PRE-OP, SAFE-OP, or OP).
 
bool exchangesProcessData () const
 Whether the device is in a process-data-exchanging state (SAFE-OP or OP, error bit clear).
 
std::expected< std::vector< uint8_t >, std::string > readSdo (uint16_t index, uint8_t subindex) const
 Reads an object dictionary entry from the device (CoE SDO upload).
 
std::expected< void, std::string > writeSdo (uint16_t index, uint8_t subindex, std::span< const uint8_t > data) const
 Writes an object dictionary entry to the device (CoE SDO download).
 
std::expected< std::vector< uint8_t >, std::string > readFile (const std::string &filename) const
 Reads a file from this device via File over EtherCAT (FoE).
 
std::expected< void, std::string > writeFile (const std::string &filename, std::span< const uint8_t > data) const
 Writes a file to this device via File over EtherCAT (FoE).
 
std::expected< void, std::string > readRegister (uint16_t address, std::span< uint8_t > data) const
 Reads bytes from an ESC register on this device.
 
std::expected< void, std::string > writeRegister (uint16_t address, std::span< const uint8_t > data) const
 Writes bytes to an ESC register on this device.
 
std::expected< std::vector< uint8_t >, std::string > readSii () const
 Reads this device's raw Slave Information Interface (SII / EEPROM) image.
 
std::expected< void, std::string > writeSii (std::span< const uint8_t > data) const
 Writes a raw SII (EEPROM) image to this device.
 
std::expected< void, std::string > initializeParameters (bool readValues=false, bool useCompleteAccess=true)
 Enumerates the device's CoE object dictionary and populates parameters().
 
std::expected< void, std::string > readFlatPdoMapping ()
 Reads the device's PDO mapping from its assignment and mapping objects.
 
const FlatPdoMappingflatPdoMapping () const
 Returns the device's PDO mapping. Empty until readFlatPdoMapping() succeeds.
 
std::expected< PdoMapping, std::string > readPdoMapping ()
 Reads the device's PDO mapping grouped by mapping object (0x16xx / 0x1Axx).
 
std::expected< void, std::string > writePdoMapping (const PdoMapping &mapping)
 Writes a new PDO mapping to the device via SDO, then reads it back to verify.
 
std::expected< void, std::string > setValue (uint16_t index, uint8_t subindex, DeviceParameterValue newValue)
 Stores a parameter's value locally, without any bus access (the typed setter).
 
std::expected< DeviceParameterValue, std::string > setValueFromBytes (uint16_t index, uint8_t subindex, std::span< const uint8_t > bytes)
 Sets the parameter's value from its raw on-the-wire bytes (the bytes-domain setter).
 
std::expected< std::vector< uint8_t >, std::string > valueAsBytes (uint16_t index, uint8_t subindex) const
 Returns the parameter's value as its raw on-the-wire bytes (the bytes-domain getter).
 
const std::unordered_map< uint32_t, DeviceParameter > & parameters () const
 Returns the parameter map, keyed by makeParameterKey(index, subindex). Empty until initializeParameters() is called.
 
std::vector< DeviceParameterparametersOrdered () const
 Returns all parameters sorted ascending by (index, subindex).
 
const DeviceParameterparameter (uint16_t index, uint8_t subindex) const
 Looks up a parameter by (index, subindex). O(1).
 
std::optional< DeviceParameterValuevalue (uint16_t index, uint8_t subindex) const
 Returns a copy of a parameter's cached value (the typed cache getter), no bus access.
 
std::optional< DeviceParameterparameterCopy (uint16_t index, uint8_t subindex) const
 Returns a copy of a full parameter struct (value + metadata), no bus access.
 
std::optional< uint16_t > dataType (uint16_t index, uint8_t subindex) const
 Returns a parameter's declared ETG.1020 data-type code, thread-safely (cache lock).
 
std::expected< DeviceParameterValue, std::string > readParameter (uint16_t index, uint8_t subindex)
 Reads a parameter value, keeping the cached store in sync.
 
std::expected< void, std::string > readAllParameters (bool useCompleteAccess=true)
 Refreshes the cached value of every readable parameter, keeping the list intact.
 
std::expected< void, std::string > writeParameter (uint16_t index, uint8_t subindex, DeviceParameterValue newValue)
 Writes a parameter value, always updating the cache first.
 
template<typename T >
std::expected< void, std::string > writeValue (uint16_t index, uint8_t subindex, T newValue)
 Typed convenience wrapper for writeParameter.
 
template<typename T >
std::expected< T, std::string > readValue (uint16_t index, uint8_t subindex)
 Typed convenience wrapper for readParameter.
 

Detailed Description

Represents a single node on the fieldbus.

Holds the node's bus position, immutable identity read from EEPROM, and a reference to the fieldbus driver for SDO and state operations.

Constructor & Destructor Documentation

◆ Device()

mm::node::Device::Device ( uint16_t  slavePosition,
mm::comm::FieldbusDriver driver,
ProcessData processData = nullptr,
const ParameterCache parameterCache = nullptr 
)

Constructs a device, reading identity from the driver at slavePosition.

Parameters
slavePosition1-based position on the fieldbus (0 is reserved for the master).
driverFieldbus driver; lifetime must exceed that of this object.
processDataLive process-data runtime, or nullptr for SDO-only operation. When supplied (by DeviceManager), readParameter / writeParameter prefer the live PDO image while the device is exchanging and fall back to SDO otherwise. Lifetime must exceed that of this object.
parameterCacheOn-disk cache of object-dictionary definitions, or nullptr to always enumerate live. When supplied (by DeviceManager), initializeParameters loads definitions from it on a hit and populates it on a miss. Lifetime must exceed that of this object.

Member Function Documentation

◆ dataType()

std::optional< uint16_t > mm::node::Device::dataType ( uint16_t  index,
uint8_t  subindex 
) const

Returns a parameter's declared ETG.1020 data-type code, thread-safely (cache lock).

The data type is immutable once initializeParameters has populated the entry, but the map itself can be rebuilt off the caller's thread, so reading it under the lock is the safe way for an off-thread consumer (e.g. capturing a PDO decode spec) to obtain it.

Parameters
indexCoE object index.
subindexCoE object subindex.
Returns
The data-type code, or nullopt if the parameter is unknown.

◆ exchangesProcessData()

bool mm::node::Device::exchangesProcessData ( ) const

Whether the device is in a process-data-exchanging state (SAFE-OP or OP, error bit clear).

Derived live from the driver's cached AL status. When false (INIT / PRE-OP / BOOT) the device does not participate in the LRW cycle, so its region of the process image is stale — PDO-mapped parameter access must use SDO, not the shared buffers. Lets a partially-operational bus route each device correctly.

◆ flatPdoMapping()

const FlatPdoMapping & mm::node::Device::flatPdoMapping ( ) const

Returns the device's PDO mapping. Empty until readFlatPdoMapping() succeeds.

◆ initializeParameters()

std::expected< void, std::string > mm::node::Device::initializeParameters ( bool  readValues = false,
bool  useCompleteAccess = true 
)

Enumerates the device's CoE object dictionary and populates parameters().

Requires the device to be in PRE-OP, SAFE-OP, or OP (mailbox communication active). One DeviceParameter is created per (index, subindex) pair returned by the SDO Info service, with value pre-initialised to a type-appropriate zero. When readValues is true each entry is additionally read and the decoded value stored on the parameter; entries that fail to read keep their default value and the call still succeeds (per-entry errors are logged).

When useCompleteAccess is true, multi-subindex objects (ARRAY/RECORD) are read with a single CoE Complete Access upload instead of one upload per subindex — far fewer mailbox round-trips. Support is probed once: if the slave rejects the first CA read, the whole pass falls back to per-subindex reads. It has no effect unless readValues is true.

Calling this method again replaces the existing parameter map.

Parameters
readValuesWhen true, follow up each entry with an SDO upload.
useCompleteAccessWhen true, use CoE Complete Access for multi-subindex objects.
Returns
Void on success, or an error string if the object dictionary enumeration itself fails (the slave does not support SDO Info, or all retries timed out).

◆ mailboxActive()

bool mm::node::Device::mailboxActive ( ) const

Whether the device's CoE/SDO mailbox is currently active (AL state PRE-OP, SAFE-OP, or OP).

Mailbox communication is available in PRE-OP and above per the EtherCAT state machine, independent of the AL error indicator — a device in SAFE-OP+error still answers mailbox requests. INIT has no mailbox and BOOT's is FoE-only, so both report false. Derived live from the fieldbus driver's cached AL status (FieldbusDriver::slaveState) — no copy is stored here. When false, readParameter / writeParameter operate on the cached value only and never touch the bus. Reflects the last state the driver read; call DeviceManager::getDeviceStates to refresh from the hardware.

◆ name()

const std::string & mm::node::Device::name ( ) const

Human-readable node name from SII EEPROM.

◆ parameter()

const DeviceParameter * mm::node::Device::parameter ( uint16_t  index,
uint8_t  subindex 
) const

Looks up a parameter by (index, subindex). O(1).

Returns
Pointer to the parameter, or nullptr if no such entry exists.
Warning
Returns a raw pointer into the parameter map; not synchronised against the cache lock. Call on the control-plane thread only. Off-thread readers use the thread-safe value / dataType getters below, which return copies under the lock.

◆ parameterCopy()

std::optional< DeviceParameter > mm::node::Device::parameterCopy ( uint16_t  index,
uint8_t  subindex 
) const

Returns a copy of a full parameter struct (value + metadata), no bus access.

The struct-level analogue of value: a deep copy taken under the cache lock, so it is safe to call off the control-plane thread (unlike parameter, which hands out a raw pointer). Reflects the last value stored by a read/refresh; it does not itself touch the bus.

Parameters
indexCoE object index.
subindexCoE object subindex.
Returns
A copy of the parameter, or nullopt if the parameter is unknown.

◆ parameters()

const std::unordered_map< uint32_t, DeviceParameter > & mm::node::Device::parameters ( ) const

Returns the parameter map, keyed by makeParameterKey(index, subindex). Empty until initializeParameters() is called.

◆ parametersOrdered()

std::vector< DeviceParameter > mm::node::Device::parametersOrdered ( ) const

Returns all parameters sorted ascending by (index, subindex).

Copies the map into a vector and sorts on the packed key. O(N log N) — call when you need stable iteration order (e.g. JSON serialisation, UI listings) rather than O(1) lookup.

◆ productCode()

uint32_t mm::node::Device::productCode ( ) const

Product code from EEPROM.

◆ readAllParameters()

std::expected< void, std::string > mm::node::Device::readAllParameters ( bool  useCompleteAccess = true)

Refreshes the cached value of every readable parameter, keeping the list intact.

Re-reads each entry already in the map (it does not re-enumerate the object dictionary — use initializeParameters for that). PDO-mapped objects are read from the live process image when exchanging; everything else is read over the mailbox — as one CoE Complete Access upload per multi-subindex ARRAY/RECORD when useCompleteAccess is true (probed once, with per-object fallback), or one SDO upload per subindex otherwise. The objects are snapshotted under the lock first, then read with the lock released between objects (each transfer holds it for one round-trip), so a concurrent cached read of this device never waits for the whole — potentially multi-second — sweep.

Write-only objects are skipped (an SDO upload of one would abort). Best-effort, like initializeParameters(readValues=true): an entry that fails to read keeps its cached value and is logged, and the call still succeeds so one bad object never blocks the rest.

Parameters
useCompleteAccessWhen true, use CoE Complete Access for multi-subindex objects read over the mailbox.
Returns
Void on success (the always-taken best-effort path), or an error string if the device has no parameters loaded yet (call initializeParameters first).

◆ readFile()

std::expected< std::vector< uint8_t >, std::string > mm::node::Device::readFile ( const std::string &  filename) const

Reads a file from this device via File over EtherCAT (FoE).

Parameters
filenameFoE filename as recognised by the slave firmware.
Returns
File bytes on success, or an error string if the transfer fails.

◆ readFlatPdoMapping()

std::expected< void, std::string > mm::node::Device::readFlatPdoMapping ( )

Reads the device's PDO mapping from its assignment and mapping objects.

Walks the PDO assignment objects (0x1C12 for outputs/RxPDO, 0x1C13 for inputs/TxPDO) and the mapping objects they reference (0x16xx / 0x1Axx) via SDO upload, producing one PdoMappingEntry per mapped object with its bit offset and width within the slave's process-data window. Requires the device to be in PRE-OP, SAFE-OP, or OP (mailbox communication active).

A direction whose assignment object is absent or assigns nothing yields an empty list for that direction (the device simply has no PDOs in it) and is not an error. Calling this again replaces the existing mapping.

Returns
Void on success, or an error string if a mapping object referenced by an assignment cannot be read (an inconsistent mapping the caller must not exchange).

◆ readParameter()

std::expected< DeviceParameterValue, std::string > mm::node::Device::readParameter ( uint16_t  index,
uint8_t  subindex 
)

Reads a parameter value, keeping the cached store in sync.

Routing, in order:

  • When the device is exchanging (SAFE-OP/OP) and process-image access was injected, the live PDO value is taken from the process image (if the object is PDO-mapped and the bus is healthy), decoded, stored (marking it SyncState::Synced) and returned — no bus I/O.
  • Otherwise, when mailboxActive(), uploads via SDO, decodes, stores and returns it.
  • Otherwise (no mailbox) returns the cached value without touching the bus.

The parameter must already exist in the map (populated by initializeParameters).

Parameters
indexCoE object index.
subindexCoE object subindex.
Returns
The (possibly freshly read) value, or an error string if the parameter is unknown or, when online, the SDO upload / decode fails.

◆ readPdoMapping()

std::expected< PdoMapping, std::string > mm::node::Device::readPdoMapping ( )

Reads the device's PDO mapping grouped by mapping object (0x16xx / 0x1Axx).

The grouped counterpart of readFlatPdoMapping: instead of one flat list per direction, each mapping object keeps its pdoIndex and its own entries (with derived bitOffset), so the result round-trips into writePdoMapping. Reads fresh over SDO; does not touch the cached flatPdoMapping(). Requires the device to be in PRE-OP, SAFE-OP, or OP (mailbox active).

Returns
The grouped mapping, or an error string if a referenced mapping object cannot be read.

◆ readRegister()

std::expected< void, std::string > mm::node::Device::readRegister ( uint16_t  address,
std::span< uint8_t >  data 
) const

Reads bytes from an ESC register on this device.

Delegates to the fieldbus driver's readRegister using this device's slave position.

Parameters
addressESC register address (e.g. 0x0130 for DL Status).
dataOutput buffer; its size determines how many bytes are read.
Returns
Void on success, or an error string on failure.

◆ readSdo()

std::expected< std::vector< uint8_t >, std::string > mm::node::Device::readSdo ( uint16_t  index,
uint8_t  subindex 
) const

Reads an object dictionary entry from the device (CoE SDO upload).

Raw SDO read with no cache or PDO awareness — for the typed, PDO-aware path use readParameter instead.

Parameters
indexCoE object index.
subindexCoE object subindex.
Returns
The bytes transferred on success, or an error string if the mailbox transfer fails.

◆ readSii()

std::expected< std::vector< uint8_t >, std::string > mm::node::Device::readSii ( ) const

Reads this device's raw Slave Information Interface (SII / EEPROM) image.

Delegates to the fieldbus driver's readSii using this device's slave position. Decode the returned bytes with mm::comm::parseSii. EEPROM access is most reliable while the device is in INIT or PRE-OP.

Returns
The raw SII image on success, or an error string on failure.

◆ readValue()

template<typename T >
std::expected< T, std::string > mm::node::Device::readValue ( uint16_t  index,
uint8_t  subindex 
)
inline

Typed convenience wrapper for readParameter.

Refreshes the value from the device when online (otherwise serves the cache) and returns it as T — e.g. device.readValue<int32_t>(0x6064, 0). The request is type-exact; use parameter(index, subindex)->numeric() when you only need a number.

Template Parameters
TThe expected variant alternative.
Parameters
indexCoE object index.
subindexCoE object subindex.
Returns
The value as T, or an error string if the parameter is unknown, the read fails, or the stored value is not a T.

◆ revisionNumber()

uint32_t mm::node::Device::revisionNumber ( ) const

Revision number from EEPROM.

◆ serialNumber()

uint32_t mm::node::Device::serialNumber ( ) const

Serial number from EEPROM.

◆ setValue()

std::expected< void, std::string > mm::node::Device::setValue ( uint16_t  index,
uint8_t  subindex,
DeviceParameterValue  newValue 
)

Stores a parameter's value locally, without any bus access (the typed setter).

Coerces value into the parameter's declared type, stores it, and marks it SyncState::Synced. Used to reflect a value obtained out-of-band — e.g. one decoded from the process image by DeviceManager — so DeviceParameter stays the source of truth. The parameter must already exist. Unlike writeParameter this never touches the wire; it is the typed counterpart of setValueFromBytes.

Parameters
indexCoE object index.
subindexCoE object subindex.
valueValue to store; coerced to the parameter's declared type.
Returns
Void on success, or an error string if the parameter is unknown or value cannot be coerced to its type.

◆ setValueFromBytes()

std::expected< DeviceParameterValue, std::string > mm::node::Device::setValueFromBytes ( uint16_t  index,
uint8_t  subindex,
std::span< const uint8_t >  bytes 
)

Sets the parameter's value from its raw on-the-wire bytes (the bytes-domain setter).

The byte-input counterpart of setValue: decodes bytes with the parameter's declared data type, stores the result (marking it SyncState::Synced), and returns the decoded value — all under parametersMutex_ so the data-type lookup, decode, and store are one atomic step. bytes are the LSB-aligned little-endian encoding of the object's value; the source is irrelevant (a slice of the process image, an SDO upload, a test fixture).

Parameters
indexCoE object index.
subindexCoE object subindex.
bytesRaw LSB-aligned little-endian value bytes.
Returns
The decoded value, or an error string if the parameter is unknown or decoding fails.

◆ slavePosition()

uint16_t mm::node::Device::slavePosition ( ) const

Returns the 1-based position of this node on the fieldbus.

◆ value()

std::optional< DeviceParameterValue > mm::node::Device::value ( uint16_t  index,
uint8_t  subindex 
) const

Returns a copy of a parameter's cached value (the typed cache getter), no bus access.

The read counterpart of setValue, and thread-safe (taken under the cache lock) so the monitoring sampler can read it concurrently with refresher/control-plane writes. Returns the last value stored by a read/refresh; it does not itself touch the bus.

Parameters
indexCoE object index.
subindexCoE object subindex.
Returns
The cached value, or nullopt if the parameter is unknown.

◆ valueAsBytes()

std::expected< std::vector< uint8_t >, std::string > mm::node::Device::valueAsBytes ( uint16_t  index,
uint8_t  subindex 
) const

Returns the parameter's value as its raw on-the-wire bytes (the bytes-domain getter).

Reads the stored value and its declared data type under parametersMutex_ and encodes them, so a caller can stage the current setpoint into the output image without reaching into the parameter map itself. The encode counterpart of setValueFromBytes.

Parameters
indexCoE object index.
subindexCoE object subindex.
Returns
The encoded bytes, or an error string if the parameter is unknown or encoding fails.

◆ vendorId()

uint32_t mm::node::Device::vendorId ( ) const

Vendor ID from EEPROM.

◆ writeFile()

std::expected< void, std::string > mm::node::Device::writeFile ( const std::string &  filename,
std::span< const uint8_t >  data 
) const

Writes a file to this device via File over EtherCAT (FoE).

Parameters
filenameFoE filename as recognised by the slave firmware.
dataFile bytes to write.
Returns
Void on success, or an error string if the transfer fails.

◆ writeParameter()

std::expected< void, std::string > mm::node::Device::writeParameter ( uint16_t  index,
uint8_t  subindex,
DeviceParameterValue  newValue 
)

Writes a parameter value, always updating the cache first.

value is coerced into the parameter's declared data type and stored in the cache (the cache is the source of truth). Then, in order:

  • exchanging (SAFE-OP/OP) with process-image access injected and the object output-mapped: the value is staged into the output image (sent next cycle), marked SyncState::Synced, and the call returns — no SDO download.
  • online: the value is encoded and downloaded via SDO. On success the parameter is marked SyncState::Synced; on download failure it is marked SyncState::Pending and the error is returned.
  • offline: the parameter is marked SyncState::Pending and the call succeeds — the edit lives in the cache until the device comes back online and it is re-written.
Parameters
indexCoE object index.
subindexCoE object subindex.
valueValue to set; coerced to the parameter's type.
Returns
Void on success (including the offline cache-only case), or an error string if the parameter is unknown, value cannot be coerced, or an online download fails.

◆ writePdoMapping()

std::expected< void, std::string > mm::node::Device::writePdoMapping ( const PdoMapping mapping)

Writes a new PDO mapping to the device via SDO, then reads it back to verify.

Reconfigures both directions' sync-manager PDO assignment (0x1C12 outputs / 0x1C13 inputs) and the mapping objects (0x16xx / 0x1Axx) they reference, following the CoE ordering rule (ETG.1000.6 §5.6.7.4.9): a sync manager's PDO assignment is cleared to zero (which makes its mapping objects writable), each mapping object's entry count is cleared, its entries are written as packed uint32 words (index<<16 | subindex<<8 | bitLength), the entry count is restored, and finally the assignment lists the mapping objects and its own count is written. A mapping object present in the previous configuration but absent from mapping is simply left unassigned — its contents are irrelevant once it is off the sync manager, so it needs no explicit clear.

Requires the device to be in PRE-OP. The mapping and assignment objects are writable only in PRE-OP — INIT/BOOT have no CoE mailbox, and in SAFE-OP/OP the sync managers are active and the slave aborts the write. This is the "drop to PRE-OP, remap, climb back" flow: the caller takes the device to PRE-OP, calls this, then transitions it back to SAFE-OP/OP, at which point DeviceManager re-reads the mapping and rebuilds the whole-bus process image.

After writing, the mapping is read back (via readFlatPdoMapping, which also refreshes flatPdoMapping()) and compared against mapping; a mismatch, or a transient SDO failure mid-sequence, is retried up to a small fixed number of whole-mapping attempts before failing, because a single dropped mailbox frame would otherwise leave the object dictionary half-configured. The apply is idempotent, so a retry is safe.

Parameters
mappingThe desired output (RxPDO) and input (TxPDO) mapping objects, in assignment order. An empty direction clears that sync manager's assignment.
Returns
Void on success (the device's mapping matches mapping), or an error string if the device is not in PRE-OP, an entry is malformed (bit length or count out of range), an SDO write/read-back fails after all retries, or the read-back does not match.

◆ writeRegister()

std::expected< void, std::string > mm::node::Device::writeRegister ( uint16_t  address,
std::span< const uint8_t >  data 
) const

Writes bytes to an ESC register on this device.

Delegates to the fieldbus driver's writeRegister using this device's slave position.

Parameters
addressESC register address.
dataBytes to write.
Returns
Void on success, or an error string on failure.

◆ writeSdo()

std::expected< void, std::string > mm::node::Device::writeSdo ( uint16_t  index,
uint8_t  subindex,
std::span< const uint8_t >  data 
) const

Writes an object dictionary entry to the device (CoE SDO download).

Raw SDO write with no cache or PDO awareness — for the typed, PDO-aware path use writeParameter instead. Requires the device to be in PRE-OP, SAFE-OP, or OP (mailbox communication active).

Parameters
indexCoE object index.
subindexCoE object subindex.
dataBytes to write; size must match the object's length.
Returns
Void on success, or an error string if the mailbox transfer fails.

◆ writeSii()

std::expected< void, std::string > mm::node::Device::writeSii ( std::span< const uint8_t >  data) const

Writes a raw SII (EEPROM) image to this device.

Delegates to the fieldbus driver's writeSii using this device's slave position. Destructive: a malformed image can leave the device unidentifiable until re-flashed. The device adopts the new contents only after a power cycle. Most reliable while the device is in INIT or PRE-OP.

Parameters
dataRaw SII image to write (even length).
Returns
Void on success, or an error string on failure.

◆ writeValue()

template<typename T >
std::expected< void, std::string > mm::node::Device::writeValue ( uint16_t  index,
uint8_t  subindex,
newValue 
)
inline

Typed convenience wrapper for writeParameter.

Lets callers pass a bare value without constructing a DeviceParameterValue — e.g. device.writeValue(0x2030, 1, 123). newValue is coerced into the parameter's declared type, so the literal's own type need not match the object's width. Online / offline behaviour is exactly that of writeParameter.

Template Parameters
TAny type a DeviceParameterValue can hold (integers, floats, std::string, std::vector<uint8_t>).
Parameters
indexCoE object index.
subindexCoE object subindex.
newValueValue to write; coerced to the parameter's type.
Returns
Void on success (including the offline cache-only case), or an error string.

The documentation for this class was generated from the following files: