Skip to content

Instantly share code, notes, and snippets.

@mnishiguchi
Last active November 13, 2021 16:14
Show Gist options
  • Save mnishiguchi/c0222eb736da12575d515859cb4c37b5 to your computer and use it in GitHub Desktop.
Save mnishiguchi/c0222eb736da12575d515859cb4c37b5 to your computer and use it in GitHub Desktop.
Inky pHAT weather example in Elixir

Inky pHAT weather example

About

Inky pHAT is an electronic paper (ePaper / eInk / EPD) display for Raspberry Pi.

Let's do something similar to Pimoroni's Inky pHAT weather example in Elixir. Here is Pimoroni's Python code.

Underjord's Youtube video Raspberry Pi, eInk and Nerves with Livebook introduces you to the basics of Inky on Nerves firmware.

Dependencies

Add these Elixir packages to your list of dependencies in mix.exs:

def deps do
  [
    {:inky, "~> 1.0"},
    {:chisel, "~> 0.2"}
  ]
end

Start Inky server

display_type = IO.gets("Display type") |> String.trim() |> String.to_existing_atom()
accent = IO.gets("Accent") |> String.trim() |> String.to_existing_atom()

# Start an Inky server
{:ok, inky_pid} = Inky.start_link(display_type, accent)

Load BDF fonts

font_name = IO.gets("Font") |> String.trim()
fonts_dir = "/data/fonts" |> tap(&File.mkdir_p/1)
font_path = Path.join([fonts_dir, "#{font_name}.bdf"])

font_url =
  "https://raw.githubusercontent.com/olikraus/u8g2/master/tools/font/bdf/#{font_name}.bdf"

if File.exists?(font_path) do
  IO.puts("Already exists #{font_path}")
else
  {:ok, {{_, 200, _}, _headers, body}} = :httpc.request(font_url)
  IO.puts("Downloaded font #{font_name}")
  File.write(font_path, List.to_string(body))
end

IO.puts("Loading font #{font_path}")
{:ok, chisel_font} = Chisel.Font.load(font_path)

Get weather info

weather_url = "https://wttr.in/?format=j1"
{:ok, {{_, 200, _}, _headers, body}} = :httpc.request(weather_url)
parsed_body = body |> List.to_string() |> Jason.decode!()
weather_info = hd(parsed_body["current_condition"])

Print pixels on Inky

clear_display_fun = fn ->
  Inky.set_pixels(inky_pid, fn _x, _y, _w, _h, _pixels -> :white end, push: :skip)
end

print_text_fun = fn text, {x, y}, color, opts ->
  put_pixel_fun = fn x, y -> Inky.set_pixels(inky_pid, %{{x, y} => color}, push: :skip) end
  Chisel.Renderer.draw_text(text, x, y, chisel_font, put_pixel_fun, opts)
end

clear_display_fun.()

"""
#{weather_info["localObsDateTime"]}
#{hd(weather_info["weatherDesc"]) |> Map.fetch!("value")}
Feels like #{weather_info["FeelsLikeF"]}°
"""
|> IO.inspect()
|> print_text_fun.({10, 10}, :black, size_x: 2, size_y: 2)

# Push the pixels in bulk
Inky.set_pixels(inky_pid, %{}, push: :await)
@mnishiguchi
Copy link
Author

mnishiguchi commented Nov 13, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment