Current section
Files
Jump to
Current section
Files
lib/dsmr/telegram.ex
defmodule DSMR.Telegram do
@type t() :: %__MODULE__{
header: DSMR.Telegram.Header.t(),
checksum: DSMR.Telegram.Checksum.t(),
data: [DSMR.Telegram.COSEM.t() | DSMR.Telegram.MBus.t()]
}
defstruct header: nil, checksum: nil, data: []
defmodule OBIS do
@type t() :: %__MODULE__{
code: String.t(),
medium: atom(),
channel: integer(),
tags: [keyword()]
}
defstruct code: nil, medium: nil, channel: nil, tags: nil
def new({:obis, [medium, channel | tags]}) do
code = "#{medium}-#{channel}:#{Enum.join(tags, ".")}"
medium = interpretet_medium(medium)
tags = interpretet_tags(tags)
%OBIS{code: code, medium: medium, channel: channel, tags: tags}
end
defp interpretet_medium(0), do: :abstract
defp interpretet_medium(1), do: :electricity
defp interpretet_medium(6), do: :heat
defp interpretet_medium(7), do: :gas
defp interpretet_medium(8), do: :water
defp interpretet_medium(_), do: :unknown
defp interpretet_tags([0, 2, 8]), do: [general: :version]
defp interpretet_tags([1, 0, 0]), do: [general: :timestamp]
defp interpretet_tags([96, 1, 1]), do: [general: :equipment_identifier]
defp interpretet_tags([96, 14, 0]), do: [general: :tariff_indicator]
defp interpretet_tags([1, 8, 1]), do: [energy: :total, direction: :consume, tariff: :low]
defp interpretet_tags([1, 8, 2]), do: [energy: :total, direction: :consume, tariff: :normal]
defp interpretet_tags([2, 8, 1]), do: [energy: :total, direction: :produce, tariff: :low]
defp interpretet_tags([2, 8, 2]), do: [energy: :total, direction: :produce, tariff: :normal]
defp interpretet_tags([1, 7, 0]), do: [power: :active, phase: :all, direction: :consume]
defp interpretet_tags([2, 7, 0]), do: [power: :active, phase: :all, direction: :produce]
defp interpretet_tags([21, 7, 0]), do: [power: :active, phase: :l1, direction: :consume]
defp interpretet_tags([41, 7, 0]), do: [power: :active, phase: :l2, direction: :consume]
defp interpretet_tags([61, 7, 0]), do: [power: :active, phase: :l3, direction: :consume]
defp interpretet_tags([22, 7, 0]), do: [power: :active, phase: :l1, direction: :produce]
defp interpretet_tags([42, 7, 0]), do: [power: :active, phase: :l2, direction: :produce]
defp interpretet_tags([62, 7, 0]), do: [power: :active, phase: :l3, direction: :produce]
defp interpretet_tags([31, 7, 0]), do: [amperage: :active, phase: :l1]
defp interpretet_tags([51, 7, 0]), do: [amperage: :active, phase: :l2]
defp interpretet_tags([71, 7, 0]), do: [amperage: :active, phase: :l3]
defp interpretet_tags([32, 7, 0]), do: [voltage: :active, phase: :l1]
defp interpretet_tags([52, 7, 0]), do: [voltage: :active, phase: :l2]
defp interpretet_tags([72, 7, 0]), do: [voltage: :active, phase: :l3]
defp interpretet_tags([96, 7, 9]), do: [power_failures: :long]
defp interpretet_tags([96, 7, 21]), do: [power_failures: :short]
defp interpretet_tags([99, 97, 0]), do: [power_failures: :event_log]
defp interpretet_tags([32, 32, 0]), do: [voltage: :sags, phase: :l1]
defp interpretet_tags([52, 32, 0]), do: [voltage: :sags, phase: :l2]
defp interpretet_tags([72, 32, 0]), do: [voltage: :sags, phase: :l3]
defp interpretet_tags([32, 36, 0]), do: [voltage: :swells, phase: :l1]
defp interpretet_tags([52, 36, 0]), do: [voltage: :swells, phase: :l2]
defp interpretet_tags([72, 36, 0]), do: [voltage: :swells, phase: :l3]
defp interpretet_tags([96, 13, 0]), do: [message: :text]
defp interpretet_tags([96, 13, 1]), do: [message: :code]
defp interpretet_tags([24, 1, 0]), do: [mbus: :device_type]
defp interpretet_tags([96, 1, 0]), do: [mbus: :equipment_identifier]
defp interpretet_tags([24, 2, 1]), do: [mbus: :measurement]
defp interpretet_tags(_), do: []
end
defmodule Value do
@type t() :: %__MODULE__{
value: integer() | float() | String.t(),
raw: String.t(),
unit: String.t()
}
defstruct value: nil, raw: nil, unit: nil
def new({:value, [[{_type, value}, {:raw, raw}], unit: unit]}) do
%Value{value: value, raw: raw, unit: unit}
end
def new({:value, [[{_type, value}, {:raw, raw}]]}) do
%Value{value: value, raw: raw}
end
end
defmodule COSEM do
@type t() :: %__MODULE__{obis: OBIS.t(), values: [Value.t()]}
defstruct obis: nil, values: []
def new([obis | values]) do
obis = OBIS.new(obis)
values = Enum.map(values, &Value.new/1)
%COSEM{obis: obis, values: values}
end
end
defmodule MBus do
@type t() :: %__MODULE__{channel: integer(), data: [DSMR.Telegram.COSEM.t()]}
defstruct channel: nil, data: []
def new(channel, cosem) do
%MBus{channel: channel, data: [COSEM.new(cosem)]}
end
end
defmodule Header do
@type t() :: %__MODULE__{manufacturer: String.t(), model: String.t()}
defstruct manufacturer: nil, model: nil
def new([{:manufacturer, manufacturer}, {:model, model}]) do
%Header{manufacturer: manufacturer, model: model}
end
end
defmodule Checksum do
@type t() :: %__MODULE__{value: String.t()}
defstruct value: nil
def new(checksum) do
%Checksum{value: checksum}
end
end
end