# `ADS.Sum`
[🔗](https://github.com/tallakt/yaads/blob/v0.1.0/lib/ads/sum.ex#L1)

Sum commands: many reads, writes, or read-writes in one ADS read-write, to an index group of the
system services with the number of them as index offset.

| Index group | Write data | Read data |
|---|---|---|
| `0xF080`, reads | each `{index_group, index_offset, length}` | the return codes, then the data of each |
| `0xF081`, writes | each `{index_group, index_offset, length}`, then the data of each | the return codes |
| `0xF082`, read-writes | each `{index_group, index_offset, read_length, write_length}`, then the data written | each return code and length read, then the data read |

Each part of the request and of the response is the same 32-bit little-endian numbers as the
single commands'. Beckhoff recommends at most 500 at a time (`max/0`): a device does them all
before its next cycle.

The results come in the order asked, each `{:ok, data}` or `:ok`, or `{:error, name}` with its
return code:

    iex> reads = [{0x4020, 0, 2}, {0x4020, 8, 1}]
    iex> {:read_write, 0xF080, 2, 11, _headers} = ADS.Sum.read(reads)
    iex> ADS.Sum.decode_read(reads, <<0::32, 0x703::32-little, 7, 0, 0>>)
    {:ok, [{:ok, <<7, 0>>}, {:error, :device_invalid_offset}]}

# `decode_read`

```elixir
@spec decode_read(
  [{ADS.index_group(), ADS.index_offset(), non_neg_integer()}],
  binary()
) ::
  {:ok, ok: binary(), error: ADS.error()}
  | {:error, {:invalid_response, binary()}}
```

The results of sum reads, from the data of the response. A device gives the data of each read
in full, but one that gives none for those that failed is understood too.

# `decode_read_write`

```elixir
@spec decode_read_write([term()], binary()) ::
  {:ok, ok: binary(), error: ADS.error()}
  | {:error, {:invalid_response, binary()}}
```

The results of sum read-writes, from the data of the response.

# `decode_write`

```elixir
@spec decode_write([term()], binary()) ::
  {:ok, [:ok | {:error, ADS.error()}]} | {:error, {:invalid_response, binary()}}
```

The results of sum writes, from the data of the response.

# `max`

```elixir
@spec max() :: 500
```

The most sub-commands Beckhoff recommends in one sum command: 500.

# `read`

```elixir
@spec read([{ADS.index_group(), ADS.index_offset(), non_neg_integer()}]) ::
  ADS.Command.request()
```

A request of sum reads, each `{index_group, index_offset, length}`.

# `read_write`

```elixir
@spec read_write([
  {ADS.index_group(), ADS.index_offset(), non_neg_integer(), binary()}
]) ::
  ADS.Command.request()
```

A request of sum read-writes, each `{index_group, index_offset, read_length, data}`, as for
getting many handles at once.

# `write`

```elixir
@spec write([{ADS.index_group(), ADS.index_offset(), binary()}]) ::
  ADS.Command.request()
```

A request of sum writes, each `{index_group, index_offset, data}`.

---

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