 
     case open_connection(token, email, jwt.bot, jwt.mqtt, jwt.vhost) do
       {:ok, conn} ->
-        Process.link(conn.pid)
         Process.monitor(conn.pid)
         {:noreply, %{state | conn: conn}}
 
       err ->
         Logger.error("Error connecting to AMPQ: #{inspect(err)}")
-        {:noreply, %{state | conn: nil}, 5000}
+        Process.send_after(self(), :timeout, 5000)
+        {:noreply, %{state | conn: nil}}
     end
   end
 
-  def handle_info({:EXIT, _pid, reason}, conn) do
-    Logger.error("Connection crash: #{inspect(reason)}")
-    {:stop, reason, conn}
+  def handle_info({:DOWN, _ref, :process, _pid, reason}, state) do
+    FarmbotCore.Logger.error(2, "AMQP Connection exit")
+    _ = close_connection(state.conn)
+    {:stop, reason, state}
   end
 
   @impl GenServer
   def handle_call(:connection, _, %{conn: conn} = state) do
     {:reply, conn, state}
+  end
+
+  def handle_call(:close, _from, %{conn: _conn} = state) do
+    FarmbotCore.Logger.error(2, "AMQP Connection closing")
+    reply = close_connection(state.conn)
+    {:stop, :close, reply, %{state | conn: nil}}
   end
 
   # Public function because the NervesHub channel requires it.

      host: mqtt_server,
      username: bot,
      password: token,
      virtual_host: vhost
    ]

    AMQP.Connection.open(opts)
  end
end

  @callback connection(GenServer.server()) :: connection()
  def connection(connection_worker \\ __MODULE__) do
    GenServer.call(connection_worker, :connection)
  end

  def close(connection_worker \\ __MODULE__) do
    GenServer.call(connection_worker, :close)
  end

  @doc "Cleanly close an AMQP channel"
