I have been following Elixir/Phoenix for some time now and finally got to work with elixir with a slack bot UltronEX and it blew me away how performing it was compared to Ruby. During this time Phoenix LiveView was gaining traction. Which got me excited but I needed something to built to play with it and that is when I came across this post about Building a Smart Mirror with Phoenix LiveView. This gave me some motivation and idea to do of my own. So during this 2020 pandemic when the world was all holed up indoor I bought a Raspberry Pi 4 and build an Ad blocking VPN with DNS over HTTPS on a Raspberry Pi4. This was my first experience working with a Pi and I liked it :).
During the pandemic like others I had also setup my work desk at home and with time as the situation in Singapore improved we started to move back to work and with that my setup was only used over weekends much of it being wasted.
Which gave me an Idea of building a smart display and use one of the screens to display it with useful information through out the day. All I needed was something small and convenient to run the code and Raspberry Pi Zero came to my mind as its quite widely used by the elixir community with the Nerves Project and seemed fit enough to run a small phoenix app and was I wrong.Don't get me wrong setting up Pi Zero was a breeze and it didn't lag on a headless setup smooth SSH-ing into it and it was easy to setup docker on it as well but turned out there were no docker images for the platform. That meant docker was no good. Not all was lost at this point as asdf-vm was available to install and I managed to install Erlang and Elixir 23.1.3 and 1.11.2 respectively(Erlang took 5 hours to build on it though) along with NodeJS using NVM (the latest supported node is 10.X on armv6). Now the hardware was ready (as I had thought prematurely)
Now it was time to start exploring LiveView and then deploy it to the Pi Zero. Got started exploring LiveView and even though there are plenty of resources and tutorial available most of them are outdated as LiveView is version 0.15.x and rapidly changing. After dabbling around the web finally came across Github example repo of LiveView creator Chris McCord. This is probably the most updated source to get you started with LiveView examples. Highly recommend that you read Phoenix LiveView docs before checking out these examples to understand how the templates and folder structure works.
Demo
To start your Phoenix server:
- Install dependencies with
mix deps.get
- Create and migrate your database with
mix ecto.setup
- Start Phoenix endpoint with
mix phx.server
or inside IEx withiex -S mix phx.server
Now you can visit localhost:4000
from your browser.
Ready to run in production? Please check our deployment guides.
Learn more
- Official website: https://www.phoenixframework.org/
- Guides: https://hexdocs.pm/phoenix/overview.html
- Docs: https://hexdocs.pm/phoenix
- Forum: https://elixirforum.com/c/phoenix-forum
- Source: https://github.com/phoenixframework/phoenix
The examples in the repo are nice and fun to play around with some having some practicality to them but not really built with a real world application perspective of software use. What I wanted was use to GenServer to pull data from different sources each on its own schedule and broadcast that to the LiveView widget that are subscribed on the topics, sounds cool?. But where do I find how to do the subscribe and broadcast part ? I had used GenServer previously and knew what I had to do with pulling data from multiple sources and had the LiveView templates setup as well but no way to send data over and decouple and make things scalable. Never underestimate the good in the Open Source community as I came across this aptly named post Real World Phoenix |> A LiveView Dashboard. This showed me how to use Phoenix built in PubSub which I had not yet explored.
drumusician / elixir_conf_live_view_dashboard
A LiveView Dashboard with ElixirConf Stats
ElixirConfLiveView
To start your Phoenix server:
- Install dependencies with
mix deps.get
- Install Node.js dependencies with
cd assets && npm install
- Start Phoenix endpoint with
mix phx.server
Now you can visit localhost:4000
from your browser.
Ready to run in production? Please check our deployment guides.
Learn more
- Official website: http://www.phoenixframework.org/
- Guides: https://hexdocs.pm/phoenix/overview.html
- Docs: https://hexdocs.pm/phoenix
- Mailing list: http://groups.google.com/group/phoenix-talk
- Source: https://github.com/phoenixframework/phoenix
Now I was able to build all of my widgets each working as a live render which means everyone running in a process of its own and if any one of them crashes it will keep the failure isolated and with each backed with a GenServer feeding it data means in case of data fetching failed or caused any error that error will not propagate to the widget and it will hold its current state with out crashing or losing the data overwritten with bad values. Now the dashboard was giving some real world vibes, ini't ? ;).
Moment of making LiveView live, cloned the repo to the Pi Zero and initiated preparing the assets with npm ci
and that is when it dawned on me that it was near impossible to practically run this on it as after even an hour it was still installing the packages and I had many more steps before running the app. If I had to go through a couple of hour cycle every time for putting changes live, it was not worth having a dashboard at it would be more of a dumb one than a smart one (I am willing to bet that the final elixir release would have managed to run well on it). Also I was going to run this as headless Pi Zero in a kiosk mode and the kiosk mode didn't work out well and by now I was exhausted to make any effort, knowing even in kiosk mode preparing each release was just too pain staking with Pi Zero being agonisingly slow for compiling/building. I wish I had seen this post from OpenFass creator One last trip down memory lane with the Raspberry Pi Zero about how slow Pi Zero can be, would have ordered Pi 3 Model A maybe but fret not, I had a plan for Pi Zero as it is still ideal to run something small, so how about I run a single instance of a browser and access the dashboard deployed somewhere else that someplace tuned out be Raspberry Pi4 I had my VPN running on. Otherwise it would have been an overkill if I had to run another cpu resource just to display or run the dashboard ;P.
I went on and containerised the project but ran into the final issue of installing speedtest cli in a container and a little searching landed me to
brennentsmith / internet-speed-logger
Open source application to track your internet download and upload speeds with an elegant web interface.
Internet Speed Logger
An application to track your internet download and upload speeds with an elegant web interface.
This is a time series based application which continuously monitors your internet connection and plots the results within a responsive web view along with providing basic aggregation of the current visible timeframe (mean). This leverages the official Speedtest.net CLI binary from Ookla to provide the best performance possible.
An early version of this service has been running for many years (~2016) and it has been instrumental for tracking internet performance issues.
To bring it online, simply run:
git clone https://github.com/brennentsmith/internet-speed-logger.git
cd internet-speed-logger
docker-compose up
Wait a couple minutes for MongoDB to initialize, and then go to http://localhost:3000
in your browser, and away you go!
In case you see errors from mongodb with:
mongodb | mkdir: cannot create directory '/bitnami/mongodb': Permission denied
mongodb exited with code 1
Try to set the persistent data…
It had the docker instructions that I needed to install the speedtest cli in my container image and have the build ready to deploy. With all the pieces in place, installed Raspbian OS on Pi Zero to use chromium and cloned the repo on the Pi 4 and voila Dashboard-0.0.1 was live
Did few iterations over the dashboard with my amateur CSS skills using Bootstrap. I am sure a lot people will know the pain for a backend developer doing CSS :P.
With all the things in place finally have the Dashboard-0.0.2 up an running ;)
The code is available on Github I have Open sourced it in hopes that people explore the new HTML over the Wire paradigm with HotWire, React Server Components and Laravel Livewire all other options along LiveView available to build similar apps. We will be seeing a lot more HTML over the wire.
Meliodas
To start Meliodas, the hard way:
- Install [speedtest cli] (https://www.speedtest.net/apps/cli)
- Install dependencies with
mix deps.get
- Install Node.js dependencies with
npm install
inside theassets
directory - Start Phoenix endpoint with
mix phx.server
To start Meliodas the easy way:
MIX_ENV=<prod/dev> SPEEDTESTARCH=<x86_64/armhf> docker-compose build
MIX_ENV=<prod/dev> SPEEDTESTARCH=<x86_64/armhf> docker-compose up
Now you can visit localhost:4000
from your browser.
Special credit to these resources
- https://github.com/chrismccord/phoenix_live_view_example
- https://github.com/brennentsmith/internet-speed-logger
- https://www.kabisa.nl/tech/real-world-phoenix-of-groter-dan-a-liveview-dashboard/
- https://medium.com/@toddresudek/building-a-smart-mirror-with-phoenix-liveview-18193ee6438f
API credits
- https://apify.com/covid-19
- http://data.fixer.io/api/latest - require sign up
- https://www.dawn.com/feeds/home - rss feed
- wttr.in - json format used
- speedtest - cli app
Signup to Sentry
and add dsn
in config if required
If you get to use it please don't forget to add it to your credits. Thanks
Top comments (1)
have you tried Nerves? nerves-project.org/
In the repo are also instructions on how to create a UI with Phoenix: github.com/nerves-project/nerves/b...
BTW, the dashboard looks great!