ExDlt645.Master (ex_dlt645 v0.1.0)

Copy Markdown View Source

DL/T 645-2007 Master collector GenServer.

Issues commands to one or more electricity meters over physical serial ports (Circuits.UART), in-memory virtual buses (ExDlt645.VirtualBus), or TCP sockets.

Serializes requests to ensure half-duplex RS-485 bus safety with :busy protection. Supports both synchronous (passive) and asynchronous event-driven (active) modes.

Summary

Functions

Returns a specification to start this module under a supervisor.

Closes the transport port.

Sends a raw DL/T 645 packet.

Sends a freeze command (0x16) to meter address.

Opens the transport port for the configured device.

Reads meter address using broadcast frame (0x13). Typically only one meter should be attached to the bus when invoking this.

Reads a data item identified by di from meter address. Returns {:ok, parsed_value} or {:ok, %Frame{}} if raw: true.

Starts the Master GenServer process.

Returns the current internal state struct of the Master.

Stops the Master GenServer process.

Broadcasts time synchronization frame (0x08).

Writes a new address to meter old_address.

Types

master_ref()

@type master_ref() :: pid() | atom()

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

close(pid)

@spec close(master_ref()) :: :ok

Closes the transport port.

custom_request(pid, raw_packet, opts \\ [])

@spec custom_request(master_ref(), binary(), keyword()) ::
  {:ok, ExDlt645.Frame.t()} | {:error, term()}

Sends a raw DL/T 645 packet.

freeze(pid, address, freeze_time_bytes, opts \\ [])

@spec freeze(master_ref(), String.t(), binary(), keyword()) :: :ok | {:error, term()}

Sends a freeze command (0x16) to meter address.

open(pid)

@spec open(master_ref()) :: :ok | {:error, term()}

Opens the transport port for the configured device.

read_address(pid, opts \\ [])

@spec read_address(master_ref(), keyword()) :: {:ok, String.t()} | {:error, term()}

Reads meter address using broadcast frame (0x13). Typically only one meter should be attached to the bus when invoking this.

read_data(pid, address, di, opts \\ [])

@spec read_data(
  master_ref(),
  String.t(),
  non_neg_integer() | binary() | String.t(),
  keyword()
) ::
  {:ok, term()} | {:error, term()}

Reads a data item identified by di from meter address. Returns {:ok, parsed_value} or {:ok, %Frame{}} if raw: true.

start_link(params, gen_opts \\ [])

@spec start_link(keyword(), keyword()) :: {:ok, pid()} | {:error, term()}

Starts the Master GenServer process.

Parameters

  • :tty - Serial device path (e.g. "/dev/ttyUSB0"), virtual target ("virtual"), or TCP spec ("tcp://192.168.1.100:10001").
  • :active - If true, asynchronous notifications are delivered to caller PID (default false).
  • :timeout - Request timeout in milliseconds (default 5,000 ms).
  • :transport - Optional explicit Transport module (defaults to resolving based on :tty).
  • :uart_opts - Options passed to UART or virtual transport (e.g. [speed: 2400, parity: :even]).

state(pid)

@spec state(master_ref()) :: %ExDlt645.Master{
  active: term(),
  cmd: term(),
  last_cmd: term(),
  parent_pid: term(),
  status: term(),
  timeout: term(),
  transport: term(),
  tty: term(),
  uart_opts: term(),
  uart_pid: term()
}

Returns the current internal state struct of the Master.

stop(pid)

@spec stop(master_ref()) :: :ok

Stops the Master GenServer process.

sync_time(pid, datetime, opts \\ [])

@spec sync_time(master_ref(), NaiveDateTime.t() | DateTime.t(), keyword()) ::
  :ok | {:error, term()}

Broadcasts time synchronization frame (0x08).

write_address(pid, old_address, new_address, opts \\ [])

@spec write_address(master_ref(), String.t(), String.t(), keyword()) ::
  :ok | {:error, term()}

Writes a new address to meter old_address.

write_data(pid, address, di, data_payload, opts \\ [])

@spec write_data(
  master_ref(),
  String.t(),
  non_neg_integer() | binary(),
  binary(),
  keyword()
) ::
  :ok | {:ok, ExDlt645.Frame.t()} | {:error, term()}

Writes data to meter address.