175 lines
4.7 KiB
Elixir
175 lines
4.7 KiB
Elixir
defmodule MqttHandler do
|
|
require GenServer
|
|
require Logger
|
|
|
|
defp build_last_will_message do
|
|
RPCMessageHandler.log_msg("Something TERRIBLE Happened. Bot going offline.")
|
|
end
|
|
|
|
@doc """
|
|
"tries to log into mqtt."
|
|
"""
|
|
def log_in(err_wait_time\\ 10000) do
|
|
mqtt_host = Map.get(token, "unencoded") |> Map.get("mqtt")
|
|
mqtt_user = Map.get(token, "unencoded") |> Map.get("bot")
|
|
mqtt_pass = Map.get(token, "encoded")
|
|
options = [client_id: mqtt_user,
|
|
username: mqtt_user,
|
|
password: mqtt_pass,
|
|
host: mqtt_host,
|
|
port: 1883,
|
|
timeout: 5000,
|
|
keep_alive: 500,
|
|
will_topic: "bot/#{bot}/from_device",
|
|
will_message: build_last_will_message,
|
|
will_qos: 0,
|
|
will_retain: 0]
|
|
case GenServer.call(MqttHandler, {:log_in, options}) do
|
|
{:error, reason} -> Logger.debug("Error connecting. #{inspect reason}")
|
|
Process.sleep(err_wait_time)
|
|
log_in(err_wait_time + 10000) # increment the sleep time for teh lawls
|
|
_ -> :ok
|
|
end
|
|
end
|
|
|
|
def init(_args) do
|
|
Mqtt.Client.start_link(%{parent: __MODULE__})
|
|
end
|
|
|
|
def start_link(args) do
|
|
handler = GenServer.start_link(__MODULE__, args, name: __MODULE__)
|
|
log_in
|
|
Logger.debug("MQTT ONLINE")
|
|
handler
|
|
end
|
|
|
|
def handle_call({:connect, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:connect_ack, _message}, from, client) do
|
|
options = [id: 24756, topics: ["bot/#{bot}/from_clients"], qoses: [0]]
|
|
spawn fn ->
|
|
NetworkSupervisor.set_time # Should NOT be here
|
|
Mqtt.Client.subscribe(client, options)
|
|
handle_call({:emit, RPCMessageHandler.log_msg("Bot Bootstrapping")}, from, client)
|
|
Command.read_all_pins # I'm truly sorry these are here
|
|
Command.read_all_params
|
|
BotSync.sync
|
|
end
|
|
keep_connection_alive
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:publish, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:subscribed_publish, message}, _from, client) do
|
|
Map.get(message, :message) |> Poison.decode! |>
|
|
RPCMessageManager.sync_notify
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:subscribed_publish_ack, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:publish_receive, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:publish_release, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:publish_complete, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:publish_ack, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:subscribe, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:subscribe_ack, _message}, from, client) do
|
|
Logger.debug("Subscribed.")
|
|
handle_call({:emit, RPCMessageHandler.log_msg("Bot Online")}, from, client)
|
|
end
|
|
|
|
def handle_call({:unsubscribe, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:unsubscribe_ack, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:ping, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:disconnect, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:pong, _message}, _from, client) do
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call({:log_in, options}, _from, client) do
|
|
case Mqtt.Client.connect(client, options) do
|
|
{:error, reason} -> {:reply, {:error, reason}, client}
|
|
_ -> {:reply, :ok, client}
|
|
end
|
|
end
|
|
|
|
def handle_call({:emit, message}, _from, client) when is_bitstring(message) do
|
|
options = [ id: 1234,
|
|
topic: "bot/#{bot}/from_device",
|
|
message: message,
|
|
dup: 1, qos: 1, retain: 0]
|
|
spawn fn -> Mqtt.Client.publish(client, options) end
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_call(thing, _from, client) do
|
|
Logger.debug("Unhandled Thing #{inspect thing}")
|
|
{:reply, :ok, client}
|
|
end
|
|
|
|
def handle_cast(event, state) do
|
|
Logger.debug("#{inspect event}")
|
|
{:noreply, state}
|
|
end
|
|
|
|
def handle_info({:keep_alive}, client) do
|
|
Mqtt.Client.ping(client)
|
|
keep_connection_alive
|
|
{:noreply, client}
|
|
end
|
|
|
|
def emit(message) when is_bitstring(message) do
|
|
GenServer.call(__MODULE__, {:emit, message})
|
|
end
|
|
|
|
defp bot do
|
|
Map.get(token, "unencoded") |> Map.get("bot")
|
|
end
|
|
|
|
defp token do
|
|
Auth.fetch_token
|
|
end
|
|
|
|
defp keep_connection_alive do
|
|
Process.send_after(__MODULE__, {:keep_alive}, 15000)
|
|
end
|
|
|
|
def terminate(reason, _state) do
|
|
Logger.debug("MqttHandler died. #{inspect reason}")
|
|
end
|
|
end
|