-
Notifications
You must be signed in to change notification settings - Fork 98
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 inv4.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 |
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 formA 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.
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 friendsNot every field that looks like a rate is one.
rate-limiton a PPP profile packs six values into one string anddst-limiton a firewall rule packs a count, a burst and a mode — those staystringon purpose.
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=1Mreads back as1000000/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
UploadorDownload.
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.
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 waitBoth 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 ::.
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.
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.
- Entity reference — which menus are covered
- Entity helpers — the verbs that are not CRUD
- Custom entities — using these types in your own entity
-
Upgrading from 3.x to 4.0 — these types replaced
stringon 28 properties