ModBoss.Schema (modboss v0.1.0)
Macros for establishing Modbus schema.
The schema allows names to be assigned to individual registers or groups of contiguous registers along with encoder/decoder functions. It also allows registers to be flagged as readable and/or writable.
Naming an address
You'll name a Modbus address 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 registers are read-only by default. Use mode: :rw
to allow both reads & writes.
Or use mode: :w
to mark a register 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 register, ModBoss will expect that
the schema module defines an encode_on_off/1
function that accepts the value to encode and
returns either {:ok, encoded_value}
or {:error, messsage}
.
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 registers, 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 registers for your mapping. If it doesn't, ModBoss will detect that and return an error during encoding.
For example, if encoding "ABC!" as ascii into a mapping with 3 registers, this would technically only "require" 2 registers (one 16-bit register for every 2 characters). However, your encoding should return a list of 3 values if that's what you've assigned to the mapping in your schema.
input to decode_*
When decoding a single register, the decode function will be passed the single value from that register as provided by your read function.
When decoding multiple registers (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
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.
Adds a read-only discrete input to a schema.
Opts
:as
— Determines which decoding functions to use when reading values. See explanation of automatic encoding/decoding.
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.
Adds a read-only input register to a schema.
Opts
:as
— Determines which decoding functions to use when reading values. See explanation of automatic encoding/decoding.
Establishes a Modbus schema in the current module.