Current section

Files

Jump to
grisp src grisp_gpio_poller.erl
Raw

src/grisp_gpio_poller.erl

% @private
-module(grisp_gpio_poller).
-behavior(gen_server).
% API
-export([start_link/0]).
% Callbacks
-export([init/1]).
-export([handle_call/3]).
-export([handle_cast/2]).
-export([handle_info/2]).
-export([code_change/3]).
-export([terminate/2]).
%--- Macros --------------------------------------------------------------------
-define(INTERVAL, 100).
-define(MONITORED_PINS, [
jumper_1,
jumper_2,
jumper_3,
jumper_4,
jumper_5
]).
%--- API -----------------------------------------------------------------------
start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, undefined, []).
%--- gen_server Callbacks ------------------------------------------------------
init(undefined) ->
erlang:send_after(0, self(), trigger),
Pins = lists:map(
fun(P) ->
{P, grisp_gpio:open(P, #{mode => input}), undefined}
end,
?MONITORED_PINS
),
{ok, refresh_state(Pins)}.
handle_call(Request, From, _State) -> error({unknown_request, Request, From}).
handle_cast(Request, _State) -> error({unknown_cast, Request}).
handle_info(trigger, State) ->
NewState = refresh_state(State),
erlang:send_after(?INTERVAL, self(), trigger),
{noreply, NewState}.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
terminate(_Reason, _State) -> ok.
%--- Internal ------------------------------------------------------------------
refresh_state(Pins) ->
[maybe_notify(P, R, S, grisp_gpio:get(R)) || {P, R, S} <- Pins].
maybe_notify(Pin, Ref, OldState, OldState) ->
{Pin, Ref, OldState};
maybe_notify(Pin, Ref, _OldState, NewState) ->
gen_event:notify(grisp_gpio_events, {Pin, NewState}),
{Pin, Ref, NewState}.