44 lines
1.2 KiB
Elixir
44 lines
1.2 KiB
Elixir
defmodule Augie.Sensor.Camera do
|
|
use GenServer
|
|
alias Phoenix.PubSub
|
|
|
|
@moduledoc """
|
|
Read frames from the camera and deposit them on the "camera" pubsub topic.
|
|
"""
|
|
|
|
@default_width 640
|
|
@default_height 480
|
|
|
|
def start_link(opts), do: GenServer.start_link(__MODULE__, opts, name: __MODULE__)
|
|
|
|
def last_frame(server), do: GenServer.call(server, :last_frame)
|
|
|
|
def init(opts) do
|
|
{:ok, camera_pid} = picam_camera_module() |> apply(:start_link, [])
|
|
|
|
width = Keyword.get(opts, :width, @default_width)
|
|
height = Keyword.get(opts, :height, @default_height)
|
|
GenServer.cast(self(), :get_frame)
|
|
|
|
Picam.set_size(width, height)
|
|
Picam.set_exposure_mode(:auto)
|
|
Picam.set_fps(24)
|
|
|
|
{:ok, %{width: width, height: height, camera: camera_pid, last_frame: "", from: nil}}
|
|
end
|
|
|
|
def handle_cast(:get_frame, %{camera: pid} = state) do
|
|
jpg = GenServer.call(pid, :next_frame)
|
|
|
|
PubSub.broadcast(Augie.PubSub, "camera", {:frame, jpg})
|
|
GenServer.cast(self(), :get_frame)
|
|
|
|
{:noreply, %{state | last_frame: jpg}}
|
|
end
|
|
|
|
def handle_call(:last_frame, _from, %{last_frame: jpg} = state) do
|
|
{:reply, jpg, state}
|
|
end
|
|
|
|
defp picam_camera_module, do: :picam |> Application.get_env(:camera, Picam.Camera)
|
|
end
|