Distributed programming made easy with Elixir
Getting Records from Mnesia
Unfortunately, Mnesia does not support SQL syntax, but it does support some basic filters like dirty_match_object
(Listing 5).
Listing 5
Getting Records
iex> # Get all the records, use :_ for "all", add a sort at the end iex> :mnesia.dirty_match_object({Pi3, :_ ,:_}) |> Enum.sort [ {Pi3, 0, '0'}, {Pi3, 1, '0'}, {Pi3, 2, '1'}, ... ] iex> # Get only Pi Values that are '1' iex> :mnesia.dirty_match_object({Pi3, :_ ,'1'}) |> Enum.sort [ {Pi3, 2, '1'} ]
A dialog from a zenity --list
command can display table output in columns (Figure 8). The last argument in the command is the data string, which fills in the defined columns. The --extra-button
option returns the button text when the button is pressed.
The script in Listing 6 (Show_gpio.exs
) reads the Mnesia results. As in the earlier example, Enum.map
and Enum.join
functions format the results as one long string for a Zenity list dialog (Figure 9).
Listing 6
Show_gpio.exs
01 #------------------- 02 # Show_Show_gpio.exs - show Mnesia table in a Zenity list dialog 03 #------------------- 04 defmodule Show_gpio do 05 def getdata() do 06 result = :mnesia.dirty_match_object({Pi3, :_ ,:_}) |> Enum.sort 07 # create a presentable string for output 08 output = Enum.map(result, fn x -> "#{elem(x,1)} #{elem(x,2)} " end) |> Enum.join 09 feedback = :os.cmd(:"zenity --list --title=Pi3_Table --text='Pin Values' --extra-button Refresh --column=Pin --column=Value #{output}") 10 if ("#{feedback}" =~ "Refresh") do 11 getdata() 12 end 13 end 14 end 15 # Start Mnesia 16 :mnesia.start() 17 # Wait for tables to update 18 :timer.sleep(1000) 19 # Show a Zenity list dialog. 20 # Refresh button to continue, other buttons to quit 21 Show_gpio.getdata()
To test that things are working, use the first project (Zen2gpio.exs
) to toggle GPIO pin values; then, the Show_gpio.exs
dialog can be refreshed to check the new values.
When the final project is running, you have an example of Elixir concurrency. The Pi3 node is populating a Mnesia table, and it is handling remote GPIO writes and CPU temperature messages.
Final Comments
Elixir with the Erlang VM offers a lot of functionality out of the box. The next steps from here would be to look at messaging between nodes and creating projects with imported Elixir libraries.
Infos
- Elixir: https://elixir-lang.org/
- Erlang: https://www.erlang.org/
- Elixir installation: https://elixir-lang.org/install.html
- GPIO utility: http://wiringpi.com/the-gpio-utility/
- Zenity: https://help.gnome.org/users/zenity/2.32/
« Previous 1 2 3
Buy this article as PDF
(incl. VAT)