DSMR.Telegram (DSMR v1.1.0)

Copy Markdown View Source

A parsed DSMR telegram.

A telegram contains the values broadcast by a smart meter at a point in time. Different DSMR versions expose different fields, so most fields are optional and remain nil when the input does not contain the corresponding OBIS code.

Unknown OBIS codes are preserved in unknown_fields instead of being rejected. This keeps parsing tolerant of regional extensions and meter-specific fields.

Summary

Functions

Decodes a hex-encoded octet-string value to its ASCII representation.

Converts a Telegram struct back to its string representation.

Types

maybe(type)

@type maybe(type) :: type | nil

obis_t()

obj_t()

@type obj_t() :: {obis_t(), value_t() | [value_t()]}

power_failure_event_t()

@type power_failure_event_t() :: [DSMR.Timestamp.t() | DSMR.Measurement.t()]

t()

@type t() :: %DSMR.Telegram{
  actual_switch_position: maybe(String.t()),
  actual_threshold_electricity: maybe(DSMR.Measurement.t()),
  checksum: String.t(),
  currently_delivered_l1: maybe(DSMR.Measurement.t()),
  currently_delivered_l2: maybe(DSMR.Measurement.t()),
  currently_delivered_l3: maybe(DSMR.Measurement.t()),
  currently_returned_l1: maybe(DSMR.Measurement.t()),
  currently_returned_l2: maybe(DSMR.Measurement.t()),
  currently_returned_l3: maybe(DSMR.Measurement.t()),
  electricity_currently_delivered: maybe(DSMR.Measurement.t()),
  electricity_currently_returned: maybe(DSMR.Measurement.t()),
  electricity_delivered_1: maybe(DSMR.Measurement.t()),
  electricity_delivered_2: maybe(DSMR.Measurement.t()),
  electricity_returned_1: maybe(DSMR.Measurement.t()),
  electricity_returned_2: maybe(DSMR.Measurement.t()),
  electricity_tariff_indicator: maybe(String.t()),
  equipment_id: maybe(String.t()),
  header: String.t(),
  mbus_devices: [DSMR.MBusDevice.t()],
  measured_at: maybe(DSMR.Timestamp.t()),
  phase_power_current_l1: maybe(DSMR.Measurement.t()),
  phase_power_current_l2: maybe(DSMR.Measurement.t()),
  phase_power_current_l3: maybe(DSMR.Measurement.t()),
  power_failures_count: maybe(String.t()),
  power_failures_log: maybe([power_failure_event_t()]),
  power_failures_long_count: maybe(String.t()),
  text_message: maybe(String.t()),
  text_message_code: maybe(String.t()),
  unknown_fields: [unknown_field_t()],
  version: maybe(String.t()),
  voltage_l1: maybe(DSMR.Measurement.t()),
  voltage_l2: maybe(DSMR.Measurement.t()),
  voltage_l3: maybe(DSMR.Measurement.t()),
  voltage_sags_l1_count: maybe(String.t()),
  voltage_sags_l2_count: maybe(String.t()),
  voltage_sags_l3_count: maybe(String.t()),
  voltage_swells_l1_count: maybe(String.t()),
  voltage_swells_l2_count: maybe(String.t()),
  voltage_swells_l3_count: maybe(String.t())
}

unknown_field_t()

@type unknown_field_t() :: {obis_t(), value_t() | [value_t()]}

value_t()

@type value_t() ::
  String.t()
  | integer()
  | float()
  | Decimal.t()
  | obis_t()
  | DSMR.Timestamp.t()
  | DSMR.Measurement.t()
  | nil

Functions

decode_octet_string(value)

@spec decode_octet_string(String.t()) :: {:ok, String.t()} | :error

Decodes a hex-encoded octet-string value to its ASCII representation.

The DSMR standard encodes octet-string values as hexadecimal ASCII: this applies to equipment_id, text_message, and DSMR.MBusDevice equipment ids. Parsed telegrams keep the raw hex value so that serialization stays lossless; use this function to read the decoded text.

Returns :error when the value is not valid hex.

Examples

iex> DSMR.Telegram.decode_octet_string("4B384547303034303436333935353037")
{:ok, "K8EG004046395507"}

iex> DSMR.Telegram.decode_octet_string("XYZ")
:error

to_string(telegram)

@spec to_string(t()) :: String.t()

Converts a Telegram struct back to its string representation.

Fields with nil or empty string values are omitted.

Examples

iex> telegram = %DSMR.Telegram{
...>   header: "ISk5\\2MT382-1000",
...>   checksum: "5106",
...>   version: "50"
...> }
iex> DSMR.Telegram.to_string(telegram)
"/ISk5\\2MT382-1000\r\n\r\n1-3:0.2.8(50)\r\n!5106\r\n"