Caveatica Socket Client
Mix.install([
{:slipstream, "~> 1.1"},
{:kino, "~> 0.12.0"},
{:jason, "~> 1.4"}
])
Section
client_config = {Caveatica.SocketClient, uri: "ws://192.168.0.7:4000/control/websocket"}
defmodule Caveatica.SocketClient do
@moduledoc """
Simulate Caveatica.
"""
use Slipstream, restart: :temporary
require Logger
@topic "control"
@status_interval _half_a_second = 500
def start_link(args) do
Slipstream.start_link(__MODULE__, args, name: __MODULE__)
end
@impl Slipstream
def init(config) do
Logger.info("info: #{inspect(config)}")
state =
config
|> connect!()
|> assign(:status_timer, nil)
|> assign(:light, "off")
{:ok, state, {:continue, :start_ping}}
end
@impl Slipstream
def handle_continue(:start_ping, socket) do
{:ok, status_timer} = :timer.send_interval(@status_interval, self(), :send_status)
{:noreply, assign(socket, :status_timer, status_timer)}
end
@impl Slipstream
def handle_connect(socket) do
Logger.info("handle_connect: calling join/2")
{:ok, join(socket, @topic, %{a: 1})}
end
@impl Slipstream
def handle_info(:send_status, socket) do
light_status = socket.assigns.light
{:ok, _ref} = push(socket, @topic, "status", %{light: light_status})
{:noreply, socket}
end
@impl Slipstream
def handle_message(@topic, "close", %{"duration" => duration}, socket) do
Logger.info("close: #{duration}")
{:ok, socket}
end
def handle_message(@topic, "open", %{"duration" => duration}, socket) do
Logger.info("open: #{duration}")
{:ok, socket}
end
def handle_message(@topic, "light", %{"state" => state}, socket) do
Logger.info("setting light: #{state}")
{:ok, assign(socket, :light, state)}
end
def handle_message(@topic, event, message, socket) do
Logger.error("Unexpected push from server: #{event} #{inspect(message)}")
{:ok, socket}
end
@impl Slipstream
def handle_disconnect(_reason, socket) do
status_timer = socket.assigns[:status_timer]
socket =
if status_timer do
:timer.cancel(status_timer)
assign(socket, :status_timer, nil)
else
socket
end
{:stop, :normal, socket}
end
end
{:ok, conn} = Kino.start_child(client_config)