gen_mqtt v0.1.1 GenMQTT behaviour

A behaviour module for implementing MMQT client processes.

Example

This example assumes an MQTT server running on the localhost on port 1883.

defmodule TemperatureLogger do
  use GenMQTT

  def start_link do
    GenMQTT.start_link(__MODULE__, nil)
  end

  def on_connect(state) do
    :ok = GenMQTT.subscribe(self, "room/+/temp", 0)
    {:ok, state}
  end

  def on_publish(["room", location, "temp"], message, state) do
    IO.puts "It is #{message} degrees in #{location}"
    {:ok, state}
  end
end

This will log to the console every time a sensor post a temperature to the broker.

Callbacks

GenMQTT defines 12 callbacs, all of them are automatically defined when you use GenMQTT in your module, letting you define the callbacks you want to customize. Six of the callbacks are similar to the ones you know from GenServer, and the GenServer documentation should be consulted for info on these. They are: init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, and code_change/3.

The remaining six are specific to GenMQTT and deals with various events in a MQTT life cycle:

  • on_connect/1 is run when the client connect or reconnect with the broker.

  • on_connect_error/2 is triggered if the connection fails for whatever reason.

  • on_disconnect/1 is run when the client disconnect from the MQTT broker.

  • on_subscribe/2 run when the client subscribes to a topic.

  • on_unsubscribe/2 run when the client stop subscribing to a topic.

  • on_publish/3 triggered everytime something is published to the broker.

All callbacks are optional. A macro will define a default function for undefined callbacks, so you only need to implement on_publish/3 if that is what you need.

Name Registration

A GenMQTT is bound to the same name registration rules as GenServers. Read more about it in the Elixir GenServer docs.

Summary

Types

Debug options supported by the start* functions

The GenEMQTT name

Return values of start* functions

Option values used by the start* functions

Functions

Make a call to the underlying state machine

Make a cast to the underlying state machine

Publish payload to topic with quality of service set to qos

Start an unlinked connection to a MQTT broker

Start a linked connection to a MQTT broker

Subscribe to one or multiple topics given a list of tuples containing the topic name and its quality of service [{"topic", 0}, ..]

Subscribe to topic with quality of service set to qos

Unsubscribe from one or more topic

Types

debug :: [:trace | :log | :statistics | {:log_to_file, Path.t}]

Debug options supported by the start* functions

from :: {pid, tag :: term}
name ::
  atom |
  {:global, term} |
  {:via, module, term}

The GenEMQTT name

on_start ::
  {:ok, pid} |
  :ignore |
  {:error, {:already_started, pid} | term}

Return values of start* functions

option ::
  {:debug, debug} |
  {:name, name} |
  {:timeout, timeout} |
  {:spawn_opt, Process.spawn_opt} |
  {:host, :inet.ip_address | binary} |
  {:port, :inet.port_number} |
  {:username, username :: binary | :undefined} |
  {:password, password :: binary | :undefined} |
  {:client, client_id :: binary} |
  {:clean_session, boolean} |
  {:last_will_topic, topic :: char_list | binary | :undefined} |
  {:last_will_msg, payload :: char_list | binary | :undefined} |
  {:last_will_qos, qos} |
  {:reconnect_timeout, pos_integer | :undefined} |
  {:keepalive_interval, pos_integer} |
  {:retry_interval, pos_integer} |
  {:proto_version, version :: pos_integer} |
  {:transport, :gen_tcp.socket | :ssl.socket}

Option values used by the start* functions

qos :: 0 | 1 | 2
topic :: [binary] | binary

Functions

call(pid, request)

Specs

call(pid, request :: term) :: term

Make a call to the underlying state machine

cast(pid, request)

Specs

cast(pid, request :: term) :: :ok

Make a cast to the underlying state machine

publish(pid, topic, payload, qos)

Specs

publish(pid, topic, payload :: binary, qos) :: :ok

Publish payload to topic with quality of service set to qos

start(module, args, options \\ [])

Specs

start(module, any, options) :: on_start

Start an unlinked connection to a MQTT broker

start_link(module, args, options \\ [])

Specs

start_link(module, any, options) :: on_start

Start a linked connection to a MQTT broker

subscribe(pid, topics)

Specs

subscribe(pid, [{topic :: binary, qos}]) :: :ok

Subscribe to one or multiple topics given a list of tuples containing the topic name and its quality of service [{"topic", 0}, ..]

subscribe(pid, topic, qos)

Specs

subscribe(pid, topic, qos) :: :ok

Subscribe to topic with quality of service set to qos

unsubscribe(pid, topic)

Specs

unsubscribe(pid, topic) :: :ok

Unsubscribe from one or more topic

Callbacks

code_change(old_vsn, state, extra)

Specs

code_change(old_vsn, state :: term, extra :: term) ::
  {:ok, new_state :: term} |
  {:error, reason :: term} when old_vsn: term | {:down, term}
handle_call(request, from, state)

Specs

handle_call(request :: term, from, state) ::
  {:reply, reply, new_state} |
  {:reply, reply, new_state, timeout | :hibernate} |
  {:noreply, new_state} |
  {:noreply, new_state, timeout | :hibernate} |
  {:stop, reason, reply, new_state} |
  {:stop, reason, new_state} when reply: term, state: term, new_state: term, reason: term
handle_cast(request, state)

Specs

handle_cast(request :: term, state) ::
  {:noreply, new_state} |
  {:noreply, new_state, timeout | :hibernate} |
  {:stop, reason :: term, new_state} when state: term, new_state: term
handle_info(msg, state)

Specs

handle_info(msg :: :timeout | term, state) ::
  {:noreply, new_state} |
  {:noreply, new_state, timeout | :hibernate} |
  {:stop, reason :: term, new_state} when state: term, new_state: term
init(state)

Specs

init(state) ::
  {:ok, state} |
  {:ok, state, timeout | :hibernate} |
  :ignore |
  {:stop, reason :: any} when state: any

Invoked when the server is started. start_link/3 and start/3 will block until it returns. state is the second term passed into either of the two start functions.

When this function returns {:ok, state} it will enter its loop and will start receiving messages from the broker, or send messages to it as soon as it has entered the connected state.

Returning {:stop, reason} will cause the start function to return {:error, reason}, and the process will exit with reason without entering its loop or calling terminate/2.

on_connect(state)

Specs

on_connect(state) :: {:ok, state} when state: term
on_connect_error(reason, state)

Specs

on_connect_error(reason, state) :: {:ok, state} when state: term, reason: :server_not_found | :server_not_available | :wrong_protocol_version | :invalid_id | :invalid_credentials | :not_authorized
on_disconnect(state)

Specs

on_disconnect(state) :: {:ok, state} when state: term
on_publish(topic, payload, state)

Specs

on_publish(topic, payload :: binary, state) :: {:ok, state} when state: term
on_subscribe(list, state)

Specs

on_subscribe([{topic, qos}], state) :: {:ok, state} when state: term
on_unsubscribe(topic, state)

Specs

on_unsubscribe(topic, state) :: {:ok, state} when state: term
terminate(reason, state)

Specs

terminate(reason, state) :: term when state: term, reason: :normal | :shutdown | {:shutdown, term} | term