ModBoss.Schema (modboss v0.1.1)

View Source

Macros for establishing Modbus schema.

The schema allows names to be assigned to individual modbus objects or groups of contiguous modbus objects along with encoder/decoder functions. It also allows objects to be flagged as readable and/or writable.

Naming a mapping

You create a ModBoss mapping with this format:

holding_register 17, :outdoor_temp, as: {ModBoss.Encoding, :signed_int}

This establishes address 17 as a holding register with the name :outdoor_temp. The raw value from the register will be passed to ModBoss.Encoding.decode_signed_int/1 before being returned.

Similarly, to set aside a group of registers to hold a single logical value, it would look like:

holding_register 20..23, :model_name, as: {ModBoss.Encoding, :ascii}

This establishes addresses 20–23 as holding registers with the name :model_name. The raw values from these registers will be passed (as a list) to ModBoss.Encoding.decode_ascii/1 before being returned.

Mode

All ModBoss mappings are read-only by default. Use mode: :rw to allow both reads & writes. Or use mode: :w to configure a mapping as write-only.

Automatic encoding/decoding

Depending on whether a mapping is flagged as readable/writable, it is expected that you will provide functions with encode_ or decode_ prepended to the value provided by the :as option.

For example, if you specify as: :on_off for a read-only mapping, ModBoss will expect that the schema module defines an encode_on_off/1 function which accepts the value to encode and returns either {:ok, encoded_value} or {:error, message}.

If the function to be used lives outside of the current module, a tuple including the module name can be passed. For example, you can use built-in translation from ModBoss.Encoding such as :boolean, :signed_int, :unsigned_int, and :ascii.

output of encode_*

Your encode function may need to encode for one or multiple objects, depending on the mapping. You are free to return either a single value or a list of values—the important thing is that the number of values returned needs to match the number of objects from your mapping. If it doesn't, ModBoss will return an error when encoding.

For example, if encoding "ABC!" as ascii into a mapping with 3 registers, these characters would technically only require 2 registers (one 16-bit register for every 2 characters). However, your encoding should return a list of length equaling what you've assigned to the mapping in your schema—i.e. in this example, a list of length 3.

input to decode_*

When decoding a mapping involving a single address, the decode function will be passed the single value from that address/object as provided by your read function.

When decoding a mapping involving multiple addresses (e.g. in ModBoss.Encoding.decode_ascii/1), the decode function will be passed a List of values.

Example

defmodule MyDevice.Schema do
  use ModBoss.Schema

  modbus_schema do
    holding_register 1..5, :model, as: {ModBoss.Encoding, :ascii}
    holding_register 6, :outdoor_temp, as: {ModBoss.Encoding, :signed_int}
    holding_register 7, :indoor_temp, as: {ModBoss.Encoding, :unsigned_int}

    input_register 200, :foo, as: {ModBoss.Encoding, :unsigned_int}
    coil 300, :bar, as: :on_off, mode: :rw
    discrete_input 400, :baz, as: {ModBoss.Encoding, :boolean}
  end

  def encode_on_off(:on), do: {:ok, 1}
  def encode_on_off(:off), do: {:ok, 0}

  def decode_on_off(1), do: {:ok, :on}
  def decode_on_off(0), do: {:ok, :off}
end

Summary

Functions

Adds a coil to a schema.

Adds a read-only discrete input to a schema.

Adds a holding register to a schema.

Adds a read-only input register to a schema.

Establishes a Modbus schema in the current module.

Functions

coil(addresses, name, opts \\ [])

(macro)

Adds a coil to a schema.

Opts

  • :mode — Makes the mapping readable/writable — can be one of [:r, :rw, :w] (default: :r)
  • :as — Determines which encoding/decoding functions to use when writing/reading values. See explanation of automatic encoding/decoding.

create_mapping(module, object_type, address_or_range, name, opts)

discrete_input(addresses, name, opts \\ [])

(macro)

Adds a read-only discrete input to a schema.

Opts

holding_register(addresses, name, opts \\ [])

(macro)

Adds a holding register to a schema.

Opts

  • :mode — Makes the mapping readable/writable — can be one of [:r, :rw, :w] (default: :r)
  • :as — Determines which encoding/decoding functions to use when writing/reading values. See explanation of automatic encoding/decoding.

input_register(addresses, name, opts \\ [])

(macro)

Adds a read-only input register to a schema.

Opts

modbus_schema(list)

(macro)

Establishes a Modbus schema in the current module.

validate_name!(env, arg2)