# `Sml.Obis`
[🔗](https://github.com/emischorr/sml_ex/blob/v0.1.0/lib/sml/obis.ex#L1)

OBIS codes (Object Identification System, IEC 62056-61).

An OBIS code consists of six groups `A-B:C.D.E*F`, e.g. `1-0:1.8.0*255` for
the total imported active energy. In SML it is sent as a 6 byte octet string.

A field set to `nil` acts as a wildcard when matching, so `parse("1-0:1.8.0")`
matches `1-0:1.8.0*255` as well as `1-0:1.8.0*0`, and `parse("1.8.0")`
additionally ignores the A and B groups.

## Aliases

`Sml.value/2`, `Sml.get/2` and `parse/1` accept these atoms (German and
English names):

  * `:bezug` - `1-0:1.8.0`
  * `:import` - `1-0:1.8.0`
  * `:bezug_t1` - `1-0:1.8.1`
  * `:import_t1` - `1-0:1.8.1`
  * `:bezug_t2` - `1-0:1.8.2`
  * `:import_t2` - `1-0:1.8.2`
  * `:einspeisung` - `1-0:2.8.0`
  * `:export` - `1-0:2.8.0`
  * `:einspeisung_t1` - `1-0:2.8.1`
  * `:export_t1` - `1-0:2.8.1`
  * `:einspeisung_t2` - `1-0:2.8.2`
  * `:export_t2` - `1-0:2.8.2`
  * `:leistung` - `1-0:16.7.0`
  * `:power` - `1-0:16.7.0`
  * `:leistung_l1` - `1-0:36.7.0`
  * `:power_l1` - `1-0:36.7.0`
  * `:leistung_l2` - `1-0:56.7.0`
  * `:power_l2` - `1-0:56.7.0`
  * `:leistung_l3` - `1-0:76.7.0`
  * `:power_l3` - `1-0:76.7.0`
  * `:strom_l1` - `1-0:31.7.0`
  * `:current_l1` - `1-0:31.7.0`
  * `:strom_l2` - `1-0:51.7.0`
  * `:current_l2` - `1-0:51.7.0`
  * `:strom_l3` - `1-0:71.7.0`
  * `:current_l3` - `1-0:71.7.0`
  * `:spannung_l1` - `1-0:32.7.0`
  * `:voltage_l1` - `1-0:32.7.0`
  * `:spannung_l2` - `1-0:52.7.0`
  * `:voltage_l2` - `1-0:52.7.0`
  * `:spannung_l3` - `1-0:72.7.0`
  * `:voltage_l3` - `1-0:72.7.0`
  * `:frequenz` - `1-0:14.7.0`
  * `:frequency` - `1-0:14.7.0`
  * `:hersteller` - `129-129:199.130.3` or `1-0:96.50.1`
  * `:manufacturer` - `129-129:199.130.3` or `1-0:96.50.1`
  * `:server_id` - `1-0:0.0.9` or `1-0:96.1.0`

# `group`

```elixir
@type group() :: 0..255 | nil
```

# `t`

```elixir
@type t() :: %Sml.Obis{
  a: group(),
  b: group(),
  c: group(),
  d: group(),
  e: group(),
  f: group()
}
```

# `aliases`

```elixir
@spec aliases() :: [atom()]
```

Returns all known alias atoms.

# `from_binary`

```elixir
@spec from_binary(&lt;&lt;_::48&gt;&gt;) :: t()
```

Creates an OBIS code from its 6 byte SML representation.

    iex> Sml.Obis.from_binary(<<1, 0, 1, 8, 0, 255>>)
    #Sml.Obis<1-0:1.8.0*255>

# `match?`

```elixir
@spec match?(t() | [t()], t()) :: boolean()
```

Returns `true` if `obis` matches `pattern`. `nil` fields in the pattern
match anything.

    iex> Sml.Obis.match?(Sml.Obis.parse!("1-0:1.8.0"), Sml.Obis.parse!("1-0:1.8.0*255"))
    true

    iex> Sml.Obis.match?(Sml.Obis.parse!("1-0:1.8.0"), Sml.Obis.parse!("1-0:2.8.0*255"))
    false

# `parse`

```elixir
@spec parse(String.t() | atom() | t()) :: {:ok, t() | [t()]} | {:error, term()}
```

Parses an OBIS code from a string, a 6 byte binary or an alias atom.

Returns a list of patterns for aliases that cover several codes, like
`:server_id`.

    iex> Sml.Obis.parse("1-0:16.7.0*255")
    {:ok, %Sml.Obis{a: 1, b: 0, c: 16, d: 7, e: 0, f: 255}}

    iex> Sml.Obis.parse("1-0:1.8.0")
    {:ok, %Sml.Obis{a: 1, b: 0, c: 1, d: 8, e: 0, f: nil}}

    iex> Sml.Obis.parse("2.8.0")
    {:ok, %Sml.Obis{a: nil, b: nil, c: 2, d: 8, e: 0, f: nil}}

    iex> Sml.Obis.parse(:bezug)
    {:ok, %Sml.Obis{a: 1, b: 0, c: 1, d: 8, e: 0, f: nil}}

    iex> Sml.Obis.parse("nonsense")
    {:error, :invalid_obis}

# `parse!`

```elixir
@spec parse!(String.t() | atom() | t()) :: t() | [t()]
```

Like `parse/1` but raises on invalid input.

# `to_string`

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

Formats the OBIS code as a string, omitting wildcard groups.

    iex> Sml.Obis.to_string(Sml.Obis.from_binary(<<1, 0, 2, 8, 0, 255>>))
    "1-0:2.8.0*255"

---

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