Skip to content

Codecs

Codecs decode the raw value exchanged with a device into the internal typed value Gridone works with — and encode it back for writing.

They are declared as an explicit codecs list on an attribute. Each entry is a single-key object whose key is the codec identifier and whose value is the argument:

- name: temperature
  data_type: float
  read_write: HR0:2
  codecs:
    - byte_convert: "float32 big_endian"

Reversible vs non-reversible

A codec is reversible if it implements both directions: decode (transport → Gridone) on read, and encode (Gridone → transport) on write. Both are applied automatically.

A non-reversible codec only implements decode. It is skipped on write (falls back to identity) — meaning it should not be used on writable attributes where the write path depends on that transformation.

Codec Reversible
json_pointer no
json_path no
scale yes
offset yes
bool_format yes
bit no
byte_convert yes
base64 yes
byte_frame yes
slice no
knx_dpt yes
mapping yes
options yes

Supported codecs

json_pointer

Decodes a value from a JSON object or string using an RFC 6901 pointer. Typically used with HTTP and MQTT responses.

Argument JSON pointer path (e.g. /data/temperature)
Input dict, JSON string, or bytes
Output any
Reversible no
codecs:
  - json_pointer: /data/temperature

Decode examples:

Input Argument Output
{"data": {"temperature": 21.5, "pressure": 1013}} /data/temperature 21.5
{"data": {"temperature": 21.5, "pressure": 1013}} /data/pressure 1013
{"enabled": true} /enabled true

json_path

Decodes a value from a JSON object using a JSONPath expression.

Argument JSONPath expression (e.g. $.sensors[0].value)
Input str, dict
Output any
Reversible no
codecs:
  - json_path: "$.sensors[0].temperature"

Decode examples:

Input Argument Output
{"sensors": [{"temperature": 21.5}]} $.sensors[0].temperature 21.5

scale

Decodes by multiplying the raw value by a factor. Encodes by dividing. Use when a device reports values in a different unit or resolution.

Argument numeric factor
Input float
Output float
Reversible yes
codecs:
  - scale: 0.1

Decode / encode examples:

Raw value Argument Decoded Encoded back
215 0.1 21.5 215
1000 0.01 10.0 1000
72 0.5 36.0 72

offset

Decodes by adding a constant to the raw value. Encodes by subtracting it. Commonly chained with scale to express a linear conversion such as (raw + offset) × scale.

Argument numeric constant
Input float
Output float
Reversible yes
codecs:
  - offset: constant_value   # e.g. -40

Decode / encode examples:

Raw value Argument Decoded Encoded back
100 5 105 100
60 -40 20 60

bool_format

Decodes an integer 0/1 to a boolean. Encodes a boolean back to 0/1. Only "0/1" is supported as argument.

Argument "0/1"
Input int (0 or 1)
Output bool
Reversible yes
codecs:
  - bool_format: "0/1"

Decode / encode examples:

Raw value Decoded Encoded back
0 false 0
1 true 1

bit

Decodes a single bit from a 16-bit register into a boolean. Used for dry-contact bit images, where many booleans are packed into one holding register. The argument is the 0-based bit position (0 = least significant bit, 15 = most significant).

Argument bit index 015
Input int (16-bit register value)
Output bool
Reversible no
codecs:
  - bit: 2

Decode examples:

Raw register Argument Output
0b0000_0000_0000_0101 0 true
0b0000_0000_0000_0101 1 false
0b0000_0000_0000_0101 2 true
0b0000_0001_0000_0000 8 true

byte_convert

Decodes raw register values or bytes into a typed value. Encodes back to registers/bytes for writing.

Argument format: "<type>" or "<type> <endian>". Default endianness is little_endian when omitted.

Supported types: uint8, int8, uint16, int16, bool, uint32, int32, float32, hex32, uint64, int64, float64, hex64.

Argument "<type>" or "<type> big_endian \| little_endian"
Input register value(s) or bytes
Output typed value (int, float, bool, str)
Reversible yes
codecs:
  - byte_convert: "float32 big_endian"

Decode / encode examples:

Raw registers Argument Decoded Encoded back
[0x41, 0xAC, 0x00, 0x00] float32 big_endian 21.5 [0x41, 0xAC, 0x00, 0x00]
[0x00, 0xD7] int16 big_endian 215 [0x00, 0xD7]
[0x00, 0x01] bool true [0x00, 0x01]

base64

Decodes a base64-encoded string to raw bytes. Encodes bytes back to a base64 string.

Argument any string (ignored)
Input base64 str
Output bytes
Reversible yes
codecs:
  - base64: "standard"

Decode / encode examples:

Raw value Decoded Encoded back
"AAAA" b'\x00\x00\x00' "AAAA"
"QWxpYQ==" b'Alia' "QWxpYQ=="

byte_frame

Decodes the byte immediately after a known prefix. Encodes by prepending the prefix to the value byte. Useful for proprietary binary protocols.

Argument hex prefix string (e.g. "11 05 00 13")
Input bytes
Output int
Reversible yes
codecs:
  - byte_frame: "11 05 00 13 00 55"

Decode / encode examples (prefix "11 05"):

Raw bytes Decoded Encoded back
b'\x11\x05\x03' 3 b'\x11\x05\x03'
b'\x11\x05\xFF' 255 b'\x11\x05\xFF'

slice

Decodes a subsequence from bytes or a list using Python slice notation (0-indexed).

Argument "start:end" or "start:end:step"
Input sequence (bytes, list)
Output subsequence
Reversible no
codecs:
  - slice: "0:4"

Decode examples:

Raw value Argument Output
b'\x41\xAC\x00\x00\xFF\xFF' "0:4" b'\x41\xAC\x00\x00'
[10, 20, 30, 40] "1:3" [20, 30]

knx_dpt

Decodes a raw KNX wire value using a KNX Datapoint Type. Only applicable with transport: knx.

Argument DPT identifier — "main.sub" notation (e.g. "9.001")
Input bool (1-bit DPTs) or list[int] (multi-byte DPTs)
Output typed value (float, int, bool, …)
Reversible yes
codecs:
  - knx_dpt: "9.001"  # (e.g. "1.001", "20.102", "5.001")

Decode / encode examples:

DPT Input Decoded Encoded back
1.001 true true true
9.001 [0x0F, 0xE8] 20.0 [0x0F, 0xE8]

mapping

Decodes a device value by looking it up in a user-defined dictionary, and encodes back by reversing the lookup. Use when device values are raw codes (integers or short strings) that map to meaningful internal labels.

The mapping must be bijective: every internal value must be unique so the reverse lookup is unambiguous.

Argument dict of device_value → internal_value (e.g. {1: "heat", 2: "cool"})
Input any
Output any
Reversible yes
codecs:
  - mapping:
      1: "heat"
      2: "cool"
      3: "fan"
      4: "auto"

Decode / encode examples:

Device value Mapping Decoded Encoded back
1 {1: "heat", 2: "cool", 3: "fan", 4: "auto"} "heat" 1
3 {1: "heat", 2: "cool", 3: "fan", 4: "auto"} "fan" 3

An unmapped value raises an error in both directions.


options

Enforces that a value belongs to a predefined set of primitives. Decode passes any value through; encode rejects values not in the list with an error.

Argument list of allowed str or int values
Input any
Output same value (unchanged)
Reversible yes
codecs:
  - options: ["heat", "cool", "fan", "auto"]

Encode examples:

Value Argument Result
"heat" ["heat", "cool", "fan", "auto"] "heat" — passes through
"turbo" ["heat", "cool", "fan", "auto"] error — not in options
1 [1, 2, 3] 1 — passes through

Note: options enforces only on write (encode). Reads always pass through — unexpected device values are surfaced as-is rather than silently rejected.


Chaining

Multiple codecs can be declared on the same attribute. They run in the order they appear in the codecs list.

On read (decode): top-to-bottom — each codec's output becomes the next one's input.

On write (encode): bottom-to-top — encoders run in reverse order.

Non-reversible codecs are skipped on write (identity encoder).

Integration example — a single attribute with two chained codecs:

- name: temperature
  data_type: float
  read_write: HR0
  codecs:
    - byte_convert: "int16 big_endian"
    - scale: 0.1

Example — integer register with scaling

A device reports temperature as a signed 16-bit integer in tenths of a degree (215 = 21.5 °C).

codecs:
  - byte_convert: "int16 big_endian"  # step 1: registers → int
  - scale: 0.1                        # step 2: int → float (÷10)
Direction Steps Result
Decode (read) [0x00, 0xD7]215 (byte_convert) → 21.5 (scale) 21.5
Encode (write) 21.5215 (scale) → [0x00, 0xD7] (byte_convert) [0x00, 0xD7]

Example — base64-encoded binary payload

A device returns a base64 string in a JSON response. The float value is packed at bytes 0–3.

codecs:
  - json_pointer: /data                 # step 1: extract base64 string from JSON (non-reversible)
  - base64: "standard"                  # step 2: decode to bytes
  - slice: "0:4"                        # step 3: take first 4 bytes (non-reversible)
  - byte_convert: "float32 big_endian"  # step 4: bytes → float
Direction Steps Note
Decode (read) JSON → base64 str → bytes → 4-byte slice → float full pipeline
Encode (write) not applicable json_pointer and slice are non-reversible — declare as read-only