Skip to content

Entity value types

Daniel Frantík edited this page Aug 29, 2026 · 3 revisions

Entity value types

The typed structs entity properties use instead of string, and which RouterOS spelling each one corresponds to. Read this before you compare, parse or round-trip a value: the reason these types exist is that RouterOS writes the same value differently depending on which transport asked.

⚠️ Alpha — ships in v4.0.0-alpha: tested and functional, but the API may still change before the final 4.0 release. See Connection types & capabilities.

All four are readonly struct, all convert implicitly to and from string, and all are declared nullable on entities (TikDuration?) because a record carries only the fields the router sent.

Type Used for The divergence it hides
TikDuration time spans and the words used in place of one 5s (API) vs 00:00:05 (CLI)
TikDataRate rates and sizes in bits per second 1000000 (API) vs 1M (CLI), plus 1Gbps
TikRatePair the upload/download pairs on /queue/simple 1000000/2000000 vs 1M/2M
TikRouterAddress where the router is: host, MAC, or both not a transport divergence — see below

TikDuration

A length of time, or one of the words RouterOS uses in place of one.

Value API / REST / WinBox native CLI transports
ten seconds 10s 00:00:10
five minutes 5m 00:05:00
one day 1d 1d00:00:00
200 ms 200ms 00:00:00.200
21:16:40 21h16m40s 21:16:40
no timeout none none

Same router, same field, same moment — the spelling depends only on who asked. A string property hands that straight to you, which is why these are typed.

var lease = connection.LoadSingle<IpDhcpServer>(...);

if (lease.LeaseTime?.Value is TimeSpan ts)      // a real duration
    Console.WriteLine(ts.TotalSeconds);
else
    Console.WriteLine(lease.LeaseTime?.Token);  // "none", "auto", "disabled", …

string forTheRouter = lease.LeaseTime;          // always the compact form

A word is kept, not thrown away. lease-time=none, keepalive-timeout=disabled, enabled=auto — these are real router states, and a type that could not hold them would turn one state into another rather than into an error. Token keeps the word verbatim.

ToString() always writes the compact form, which every transport accepts on write. So a value read over the CLI and written back is not silently reformatted.

TikDataRate

A rate or size in bits per second, written four ways for one value.

Spelling Where you see it
1000000 the binary API, and what ToString() writes
1M the CLI transports (print as-value)
1Mbps, 0bps, 1Gbps wherever RouterOS renders a rate for display — print stats over the CLI, /interface/ethernet monitor
unlimited, auto a word instead of a number

The suffixes are decimal, not binary: 500k is 500 000, not 512 000 — measured by writing limit-at=500k and reading back 500000.

The bps unit is not even consistent within one record: measured on RouterOS 7.24, /queue/simple print stats over the CLI writes rate=0bps/0bps while the single-valued total-rate on the same row is a bare 0.

TikDataRate? r = someEntity.MaxLimit;
long? bitsPerSecond = r?.Value;     // null when the router sent a word
string? word = r?.Token;            // "unlimited" and friends

Not every field that looks like a rate is one. rate-limit on a PPP profile packs six values into one string and dst-limit on a firewall rule packs a count, a burst and a mode — those stay string on purpose.

TikRatePair

The upload/download pair RouterOS uses for /queue/simple's max-limit, limit-at, burst-limit and burst-threshold.

API CLI
max-limit 1000000/2000000 1M/2M
var q = connection.LoadSingle<QueueSimple>(connection.CreateParameter("name", "customer-1"));
long? up   = q.MaxLimit?.Upload;
long? down = q.MaxLimit?.Download;

Two things worth knowing before you write one:

  • Writing one side means upload, with download zero. Setting max-limit=1M reads back as 1000000/0 — it does not mean "the same on both sides". That assumption silently halves a configuration.
  • There is no conversion to a single number. A pair holds two, and picking one for you would be a guess. Read Upload or Download.

The single-valued max-limit on /queue/tree reads the same on every transport and stays a plain long — it is the pairing that changes the spelling, not the magnitude.

TikRouterAddress

Where the router is. Unlike the three above this is not about a transport divergence — it exists because a router is reached by IP or by MAC, the two are alternatives rather than a pair, and both are strings so an overload cannot tell them apart.

TikRouterAddress.FromHost("192.168.88.1")                             // IP transports; MAC ones discover via MNDP
TikRouterAddress.FromMac("AA:BB:CC:DD:EE:FF")                         // MAC transports — no IP anywhere
TikRouterAddress.FromHostAndMac("192.168.88.1", "AA:BB:CC:DD:EE:FF")  // MAC transports, skipping the MNDP wait

Both together is a legitimate third case: on a MAC transport the host names the local interface to use and the MAC identifies the router, which saves up to 5 s of MNDP discovery per open.

Parse (and the implicit conversion from string) tells the two apart by shape — six hex pairs separated by : or - is a MAC and cannot be a host name or an IPv6 address, which needs eight groups or a ::.


Enums

Fields with a fixed set of RouterOS words are mapped to C# enums, each member carrying the router's spelling:

[TikEnum("in-interface")]
InInterface,

A value the enum does not know degrades that one property rather than failing the whole entity load — RouterOS adds words between versions, and losing a row because of one unrecognised option would be worse than losing the option.

MacAddress

tik4net.Objects.MacAddress is the MAC in 00:00:00:00:00:00 form, with implicit conversions both ways, used by helpers such as ExecuteWol. It is a convenience type on the entity side, not one of the transport-divergence types above.

See also

Clone this wiki locally