Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Hackathon 14

notebook.livemd

Hackathon 14

Hot Button

Interaction withe the system LED of the raspberry pi.

defmodule LED do
  @led Path.join("/sys/class/leds", "led0")

  def switch(:on) do
    File.write(Path.join(@led, "brightness"), "1")
  end

  def switch(:off) do
    File.write(Path.join(@led, "brightness"), "0")
  end
end

Various Mix.install examples: https://github.com/wojtekmach/mix_install_examples

Slack Webhook

Install elixir http client via mix.

Mix.install([
  {:castore, "~> 0.1.0"},
  {:mint, "~> 1.0"}
])

defmodule Slack do
  @url "hooks.slack.com"

  def post do
    {:ok, conn} = Mint.HTTP.connect(:https, @url, 443)

    {:ok, _conn, _request_ref} =
      Mint.HTTP.request(
        conn,
        "POST",
        Application.fetch_env!(:hot_button, :slack_webhook),
        [],
        "{\"channel\": \"#_hot_button\", \"username\": \"Hot Button\", \"text\": \"Someone pressed the hot button and it was successfully debounced by our awesome script.\", \"icon_emoji\": \":ghost:\"}"
      )
  end
end
{:ok, button_input} = Circuits.GPIO.open(21, :input)

# We will configure the button interrupts for both rising and falling.
Circuits.GPIO.set_interrupts(button_input, :both, suppress_glitches: true)
Circuits.GPIO.set_pull_mode(button_input, :pulldown)

defmodule Button do
  # The threshold is in nano seconds
  @threshold 500 * 10 ** 4

  # Watch for the button press
  def listen_forever(last \\ 0) do
    receive do
      {:circuits_gpio, _p, now, state} ->
        state
        |> to_action()
        |> receive_msg(last, now)
    end
  end

  def to_action(1), do: :on
  def to_action(0), do: :off

  def receive_msg(action, last, now) when now >= last + @threshold do
    IO.puts("#{now} #{action}")

    :ok = LED.switch(action)

    maybe_notify(action)
    listen_forever(now)
  end

  def receive_msg(_action, last, _now), do: listen_forever(last)

  def maybe_notify(:on), do: Slack.post()
  def maybe_notify(:off), do: nil
end
Button.listen_forever()