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.

Figure 8: A Zenity list in Bash.

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()
Figure 9: Elixir script showing Mnesia data.

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.

The Author

You can investigate more neat projects by Pete Metcalfe and his daughters at https://funprojects.blog.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Elixir 1.0

    Developers will appreciate Elixir's ability to build distributed, fault-tolerant, and scalable applications.

  • Xonsh

    Create lightweight Raspberry Pi scripts with Xonsh, a Python shell that lets you write scripts in Python with Bash commands mixed in.

  • RaspPi-Controlled Toy Sailboat

    With Node-RED, you can create a web dashboard that instructs a Raspberry Pi to set the rudder position on a toy sailboat.

  • WiFi Thermo-Hygrometer

    A WiFi sensor monitors indoor humidity and temperature and a Node-RED dashboard reports the results, helping you to maintain a pleasant environment.

  • Julia on the Pi

    Create GUIs and a web app that connects to sensors.

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More

News