# Flix
[![Build Status](https://efcasado.semaphoreci.com/badges/flix/branches/master.svg?style=shields)](https://efcasado.semaphoreci.com/projects/flix)
An Elixir client for the [Flic](https://flic.io/) button.
### What's in the name?
The name `Flix` is the result of combining `Fli(c)`, the name of the button, and
`(e)x`, the extension used by Elixir source files.
[Flix](https://en.wikipedia.org/wiki/Flix) is also a town in the beautiful
province of Tarragona, Catalonia, Spain.
### The Flic protocol
`Flix` implements the full Flic protocol as per described in the
[official fliclib-linux-hci GitHub repository](https://github.com/50ButtonsEach/fliclib-linux-hci/blob/master/ProtocolDocumentation.md).
### Usage
Flic buttons don't connect directly to `Flix` nor the other way around. Flic buttons connect
to a `flicd` via bluetooth. `Flix` applications also connect to `flicd` but via a TCP. See
the diagram below.
```
+------------+ command(s) +---------+ +---------------+
| +------------->| | | |
| Flix App | TCP | flicd |<--------------+ Flic Button |
| |<-------------+ | Bluetooth | |
+------------+ event(s) +---------+ +---------------+
```
You can find more information about Flic's `flicd` in its
[official page](https://github.com/50ButtonsEach/fliclib-linux-hci).
Writing a Flix application is as simple as defining a new Elixir module,
using Flix's `__using__` macro (ie. `use Flix`) and implementing Flix's
`handle_event/2` callback function.
```elixir
defmodule MyFlixApp do
use Flix
def handle_event(event, state) do
new_state = do_something(event, state)
{:ok, new_state}
end
end
```
Below is a full example of a Flix application where a counter is initialised to `0`
and increased or decreased by one when someone does single- or double-clicks a Flic
button, respectively. The code makes the following assumptions:
- `flicd` is running and reachable on `raspberrypi.local:5551`.
- The Flic button (ie. `"80:E4:DA:78:45:1B"`) has already been paired with `flicd`.
```elixir
defmodule Flix.Examples.Counter do
use Flix
alias Flix.Protocol.Events.ButtonSingleOrDoubleClickOrHold
alias Flix.Protocol.Enums.ClickType
def start(host \\ 'raspberrypi.local', port \\ 5551) do
{:ok, client} = Flix.start(__MODULE__, 0, host, port)
:ok = set_up(client)
{:ok, client}
end
def start_link(host \\ 'raspberrypi.local', port \\ 5551) do
{:ok, client} = Flix.start_link(__MODULE__, 0, host, port)
:ok = set_up(client)
{:ok, client}
end
def set_up(client) do
:ok = Flix.create_connection_channel(client, "80:E4:DA:78:45:1B", 1)
end
def stop(client) do
:ok = Flix.stop(client)
end
def handle_event(
%ButtonSingleOrDoubleClickOrHold{click_type: ClickType.SingleClick},
count
) do
new_count = count + 1
IO.puts "Count = #{new_count}"
{:ok, new_count}
end
def handle_event(
%ButtonSingleOrDoubleClickOrHold{click_type: ClickType.DoubleClick},
count
) do
new_count = count - 1
IO.puts "Count = #{new_count}"
{:ok, new_count}
end
def handle_event(event, count) do
require Logger
Logger.debug("No handle_event/2 clause in #{__MODULE__} for #{inspect(event)}")
{:ok, count}
end
end
```
### Author(s)
- Enrique Fernandez `<efcasado@gmail.com>`
### Acknowledgements
I would like to thank [BlueLabs](https://www.bluelabs.eu/) for sponsoring the
development of `Flix` by creating an opportunity for me to work on this project.
This project was conceived during BlueLabs' 2nd Hackathon (22-23 July, 2021).
[![BlueLabs](images/bluelabs-logo.png?raw=true "BlueLabs")](https://www.bluelabs.eu/)
### License
> The MIT License (MIT)
>
> Copyright (c) 2021, Enrique Fernandez
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in
> all copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> THE SOFTWARE.