# `ExDlt645.DataId`
[🔗](https://github.com/Ultraluv/ex_dlt645/blob/v0.1.0/lib/ex_dlt645/data_id.ex#L1)

DL/T 645-2007 Data Identifier (DI) specifications and value decoders/encoders.

A Data Identifier consists of 4 bytes: `DI3, DI2, DI1, DI0`.
In wire transmissions, it is transmitted in reverse order (`DI0, DI1, DI2, DI3`)
with each byte offset by `+ 0x33`.

This module recognizes all categories from Tables A.1 to A.7 of DL/T 645-2007:
- Table A.1 (DI3 = 0x00): Electric Energy (电能量)
- Table A.2 (DI3 = 0x01): Maximum Demand and Occurrence Time (最大需量及发生时间)
- Table A.3 (DI3 = 0x02): Instantaneous Variables (变量: 电压/电流/功率/功率因数/频率/温度等)
- Table A.4 (DI3 = 0x03): Event Records (事件记录)
- Table A.5 (DI3 = 0x04): Parameters (参变量: 时间/日期/地址/常数/状态字等)
- Table A.6 (DI3 = 0x05): Freeze Data (冻结数据)
- Table A.7 (DI3 = 0x06): Load Profiles (负荷记录)

# `decode_by_format`

Decodes raw payload bytes by format atom.

# `decode_value`

```elixir
@spec decode_value(non_neg_integer() | binary() | String.t(), binary()) ::
  {:ok, term()} | {:error, term()}
```

Decodes raw response payload bytes (after -0x33 subtraction) according to the DI's format.
Returns `{:ok, decoded_value}` or `{:error, reason}`.

# `encode_by_format`

Encodes value into raw payload bytes by format atom.

# `encode_value`

```elixir
@spec encode_value(non_neg_integer() | binary() | String.t(), term()) ::
  {:ok, binary()} | {:error, term()}
```

Encodes user value into raw payload bytes (before +0x33 addition) according to the DI's format.

# `from_wire_bytes`

```elixir
@spec from_wire_bytes(binary()) :: non_neg_integer()
```

Parses wire representation `<<di0, di1, di2, di3>>` back into a 32-bit Data Identifier integer.

# `lookup`

```elixir
@spec lookup(non_neg_integer() | binary() | String.t()) ::
  {:ok, ExDlt645.DataId.Info.t()} | {:error, :unknown_di}
```

Looks up metadata and parser information for the given Data Identifier.

# `to_bytes`

```elixir
@spec to_bytes(non_neg_integer() | binary() | String.t()) :: binary()
```

Converts a 32-bit Data Identifier integer into 4 bytes `<<di3, di2, di1, di0>>`.

# `to_integer`

```elixir
@spec to_integer(integer() | binary() | String.t()) :: non_neg_integer()
```

Normalizes a Data Identifier into a 32-bit unsigned integer `0xDI3_DI2_DI1_DI0`.
Accepts integers, 4-byte binaries `<<di3, di2, di1, di0>>`, or hex strings.

# `to_wire_bytes`

```elixir
@spec to_wire_bytes(non_neg_integer() | binary() | String.t()) :: binary()
```

Converts a 32-bit Data Identifier to the wire representation:
low-order byte first `<<di0, di1, di2, di3>>`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
