Parameter value types
Ta treść nie jest jeszcze dostępna w Twoim języku.
A parameter’s valueType turns the bytes its source supplies into the parameter’s
value, and a value you write back into bytes. Every value is a string of at most 1,024 characters;
numbers, booleans, and labels also carry their numeric form, except a number too large to hold
exactly (see wide integers). name selects the type:
name | Value |
|---|---|
str | Text, or the bytes as base64 or hex |
int | A whole number, or its label from repr |
num | A decimal number with ., formatted per decimalPlaces |
bool | "true" or "false", or the labels from repr |
bigint | An integer of any size, as decimal digits |
datetime | An ISO 8601 date and time |
ipaddr | A dotted IPv4 or colon IPv6 address |
macaddr | aa:bb:cc:dd:ee:ff |
geo | "lat,lon" in decimal degrees, such as "46.466667,30.716667" |
Shared settings
Section titled “Shared settings”Byte relation
Section titled “Byte relation”fromBytes (byteRelation on bigint, ipaddr and macaddr) reorders or filters the source
bytes to match the device’s byte order before they are decoded:
| Field | Values |
|---|---|
filterBytes | leave-first-byte-in-word or leave-last-byte-in-word |
swapBytesInWords | true exchanges the two bytes of every two-byte word |
swap | bytes reverses all bytes; words reverses the word order |
Numbers are decoded big-endian: the most significant byte comes first. With an empty relation {},
nothing is reordered. Modbus registers arrive in addresses order, each high byte first, so a
32-bit value that the manual lays out high word first, with the addresses listed in that order,
needs no swap.
When the addresses supply more bytes than a number needs, num and int use the last bytes. On
read, the relation applies in this order:
filterByteskeeps the first or last byte of each two-byte word: for Modbus registers, the high or the low byte.swapBytesInWords: trueexchanges the two bytes within every word.swap: "bytes"reverses the whole byte sequence;swap: "words"reverses the order of the words and keeps the bytes within each word. A last unpaired byte stays in place.
For source bytes A B C D (registers AB, then CD), with no filter:
| Relation | Bytes decoded |
|---|---|
{} | A B C D |
{ "swap": "bytes" } | D C B A |
{ "swap": "words" } | C D A B |
{ "swapBytesInWords": true } | B A D C |
{ "swapBytesInWords": true, "swap": "words" } | D C B A |
An unsigned 32-bit integer is int or num with composition.byteLength: 4 and
composition.packing: "unsigned-int"; composition.fromBytes is {} for registers sent high word
first and { "swap": "words" } for low word first. A 32-bit float is num with
composition.packing: "float32" and composition.byteLength: 4, with the same word order rules.
When the manual does not state the word order, compare a reading with a value you know.
Two parameters on the same register with leave-first-byte-in-word and leave-last-byte-in-word
give its high and low bytes, such as a firmware’s major and minor version. Writes apply the
operations in reverse; filtered-out bytes are written as zero.
Scaling
Section titled “Scaling”num, int and bigint scale the decoded number:
value = raw * multiplier + shiftFor non-linear scaling, use a transform.
Transforms
Section titled “Transforms”num, int and bigint may set:
{ "transform": { "fromRead": "x * 0.1 - 40", "toWrite": "(x + 40) * 10" } }The formulas use the formula language and must give a number. In fromRead, x (or
#1) is the decoded number after scaling; in toWrite, it is the written value, and
the result is scaled back and encoded. Without toWrite, a write is scaled back and encoded as
typed. A formula that does not compile is refused on save; a failure that depends on the value
fails the read or write with formula_error. To split one register into two values, use
filterBytes, not a transform.
Wide integers
Section titled “Wide integers”Fractional scaling and transforms are exact only within ±9,007,199,254,740,991 (2⁵³ − 1). An
eight-byte unsigned-int or signed-int can exceed that, as a large counter or fixed-point total
does:
- With a whole-number
multiplierandshiftand nofromRead,numandintscale exactly. A result beyond the limit is a decimal string with no numeric form. - With a fractional
multiplierorshift, or afromRead, a raw value beyond the limit fails the read withdecode_error, even when the scaled value would fit. bigintscales exactly at any size, by whole numbers only. Its transforms need a value within the limit and must give a whole number.
To show such a value in fractional units, read the raw count as bigint with multiplier "1"
over the register span the device documents, and divide where it is shown with exact decimal
arithmetic. For a totalizer counting 0.001 m³, raw 9007199254740993 is 9007199254740.993 m³;
turning the string into a number first loses the last digit.
Unavailable readings
Section titled “Unavailable readings”Some devices send a fixed raw value, such as 0x8000, when they have no reading. On num and
int, readUnavailableValue names that raw value as an integer, after byte order and signedness
but before scaling and transforms. A matching read fails with decode_error, reason
value_unavailable, and is not recorded in history. For example, a signed 16-bit temperature that
sends 0x8000 uses readUnavailableValue: -32768. Writes are not affected.
Write validation
Section titled “Write validation”writeValidation sets the limits a written value must meet: min and max, a length, or a list
of allowed values. Each of its members must be present; null means no limit. A value outside them
fails with encode_error and a reason such as write_value_below_min,
write_value_exceeds_max, write_invalid_number, write_value_not_allowed,
write_value_too_short or write_value_too_long.
Zones and labels
Section titled “Zones and labels”zones on num sets the thresholds where a value turns green, orange or red on screen: min,
lowOrangeBegins, greenBegins, highOrangeBegins, highRedBegins and max. repr on int
gives labels, each with an optional zone, to listed values; repr on bool gives labels to true
and false. A label is one text or one per language. Zones only change how a value is shown; a
label replaces the value, while the numeric form stays a number.
| Field | Notes |
|---|---|
fromBytes | Byte relation |
encoding | ascii, utf8, utf16le, base64 or hex |
nulTerminated | Text stops at the first NUL byte; true by default |
writeValidation | minLength, maxLength, allowedValues, each required; null for no limit |
nulTerminated applies to ascii, utf8 and utf16le; hex and base64 keep every byte. When
it is false, only trailing NUL padding is removed. ASCII is strict: bytes above 0x7f read as
the replacement character U+FFFD, and ASCII writes refuse other characters.
| Field | Notes |
|---|---|
composition.fromBytes | Byte relation |
composition.byteLength | 1–8 |
composition.packing | unsigned-int, signed-int, bcd-int, float32 or float64 |
multiplier, shift | Scaling |
decimalPlaces | 0–15, or null (the default) |
readUnavailableValue | Optional; see unavailable readings |
transform | Optional; see transforms |
writeValidation.min / max | Required numbers; null for no limit |
zones | Optional; see zones and labels |
With decimalPlaces set, the value always has that many decimals, trailing zeros included. With
null, it is rounded to as many decimals as the multiplier has, and trailing zeros are dropped: a
multiplier of 0.01 gives at most two decimals, and a multiplier of 1 gives whole numbers, also
for a float32. The numeric form is not rounded.
The packings float16, decimal16, decimal32 and decimal64 cannot be read or written.
The composition is either:
- from bytes:
byteLength1–8,packingunsigned-int,signed-intorbcd, andfromBytes; or - from bits:
fromBits, a list of 1–53 bit indices (0–63, counted as forbool), andsigned.
Also: multiplier, a whole-number shift, optional readUnavailableValue and transform,
writeValidation with whole-number min and max, and optional repr: a list of
{ value, repr, zone }. When a reading matches a value, the parameter’s value is its label.
Writes accept numbers and the labels in any language.
| Field | Notes |
|---|---|
bit | 0–63, or null: then any non-zero value is true |
repr | Optional { true, false } labels, each up to 100 characters |
Writes accept "true", "false", and the labels in any language.
bit counts in the source bytes in address order: byte floor(bit / 8), then bit bit % 8 from
that byte’s least significant bit. Bit 0 is the low bit of the first byte, and bit 8 the low bit of
the second. A Modbus register arrives high byte first, so its least significant bit is bit 8.
Bit N of a register as a device manual numbers it (bit 0 the least significant) is bit N + 8 for
N below 8, and bit N − 8 for N from 8 to 15. For a 32-bit value in two registers sent high word
first, the value’s bit N is bit N XOR 24: bits 0–7 are bit 24–31, and bits 24–31 are bit 0–7.
bigint
Section titled “bigint”byteRelation, signed, and multiplier and shift as whole-number strings (multiplier not
"0"); an optional transform; and writeValidation with min, max and allowedValues as
whole-number strings. The value is decimal digits with no numeric form, whatever its size. See
wide integers.
datetime
Section titled “datetime”composition.kind is one of:
| Kind | Bytes |
|---|---|
timestamp-sec-32 | Unix time in seconds |
timestamp-msec-32 | A 32-bit millisecond counter |
timestamp-days-32 / timestamp-days-16 | A day counter |
iso-8601-string | ISO 8601 text |
datetime | Year, month, day, hour, minute, second at byte or word positions, with optional timezone offset |
Also: displayFormat (up to 100 characters; Setup suggests YYYY-MM-DD HH:mm:ss), shiftSeconds,
and timezone, an IANA name, or null for UTC.
With timestamp-sec-32, composition.zeroIsUnavailable: true makes a raw zero mean “no date”:
such a read fails with decode_error, reason timestamp_unavailable, and records nothing in
history, and a write that would send zero is refused. Without it, zero reads as the Unix epoch,
1970-01-01.
The value is always ISO 8601. The app shows dates as YYYY-MM-DD HH:mm:ss in the browser’s
timezone, and reports in the report’s timezone.
ipaddr
Section titled “ipaddr”variant (ipv4 or ipv6) and byteRelation.
macaddr
Section titled “macaddr”byteRelation only.
The value is "lat,lon" in decimal degrees. A write with a latitude outside −90…90 or a longitude
outside −180…180 is refused. Setup and the live value editor show latitude and longitude as two
fields. geo has no numeric form.
The composition’s encoding is one of:
scalar:latitudeandlongitudeeach havefromBytes,position,byteLength1–8,packingunsigned-int,signed-int,float32orfloat64, andmultiplierandshift(degrees = raw * multiplier + shift). This covers floats and whole arcseconds (multiplier1/3600).dms:degrees,minutesandsecondsbyte fields for each axis, and a sharedquadrant(0NE,1NW,2SE,3SW).
decimalPlaces (0–15 or null) formats both axes like num. With null, scalar takes the
decimals from each axis’s multiplier, and dms uses seven decimals.
Source bytes and value types
Section titled “Source bytes and value types”The value type decodes the bytes its source supplies:
| Source | Bytes supplied | Value type that decodes them |
|---|---|---|
Calc returnFormat: "int" | 4 bytes, signed 32-bit integer, big-endian | int / num, byteLength: 4, signed-int |
Calc returnFormat: "float" | 8 bytes, IEEE 754 binary64, big-endian | num, float64, byteLength: 8 |
| One holding or input register | 2 bytes, high byte first | int / num, byteLength: 2 |
| Two registers holding a float | 4 bytes in register order | num, float32, with swap for the device’s word order |
| Coil or discrete input | 1 byte per address, 0x00 or 0xff | bool (bit null or a specific bit) |
| Const text | The stored bytes | str with the stored encoding |
A value type that does not match its source bytes usually saves and then fails at read or write
time with decode_error or encode_error, so read the parameter once after you save it. A Modbus
source with fewer addresses than a fixed-width value type needs is refused on save
(modbus_source_too_short).
Switching the type’s name in Setup replaces the whole value type with the defaults of the new
type.
Write strings
Section titled “Write strings”A write sends the value as a string:
| Value type | value to send |
|---|---|
num / int | A decimal number ("21.5", "3"); int also accepts its labels |
bool | "true" or "false", or the labels |
str | The text, encoded by the type’s encoding |
bigint | Decimal digits |
datetime | ISO 8601 |
ipaddr / macaddr / geo | The forms in the table at the top |
A value that fails writeValidation fails with encode_error and a reason; a disabled parameter
fails with param_disabled. See
live value procedures.
Example
Section titled “Example”A 32-bit float in two registers sent low word first, shown with two decimals, writable from −40 to 120:
{ "name": "num", "composition": { "fromBytes": { "swap": "words" }, "byteLength": 4, "packing": "float32" }, "multiplier": 1, "shift": 0, "decimalPlaces": 2, "transform": null, "writeValidation": { "min": -40, "max": 120 }, "zones": null}