Current section
Files
Jump to
Current section
Files
lib/scd30.ex
defmodule SCD30 do
use GenServer
require Logger
alias SCD30.Comm
@default_polling_interval_ms 10_000
@default_measuring_interval_ms 10_000
def start_link(init_arg \\ []) do
options = Keyword.take(init_arg, [:name])
GenServer.start_link(__MODULE__, init_arg, options)
end
def measure(pid) do
GenServer.call(pid, :measure)
end
@impl true
def init(options \\ []) do
# Sample options keyword list :
# [transport: {"i2c-1", 0x5B}]
# [polling_interval: 10_000]
# [measuring_interval: 10_000]
polling_interval = Keyword.get(options, :polling_interval, @default_polling_interval_ms)
measuring_interval = Keyword.get(options, :measuring_interval, @default_measuring_interval_ms)
{bus_name, device_addr} = Keyword.get(options, :transport, Comm.discover())
Logger.info(
"Starting PMSA00I on bus: #{bus_name}, address: #{device_addr} : " <>
"Polling interval : #{polling_interval}"
)
i2c = Comm.open(bus_name)
SCD30.Cmds.MEASUREMENT_INTERVAL.set(i2c, device_addr, div(measuring_interval, 1000))
SCD30.Cmds.CONTINUOUS_MEASUREMENT.start(i2c, device_addr)
:timer.send_interval(polling_interval, :measure)
state = %{
i2c: i2c,
device_addr: device_addr,
last_reading: %SCD30.Measurement{}
}
{:ok, state}
end
@impl true
def handle_info(
:measure,
%{i2c: i2c, device_addr: device_addr} = state
) do
updated_with_reading =
case SCD30.Cmds.DATA_READY.read(i2c, device_addr) do
true ->
%{
state
| last_reading: SCD30.Cmds.READ_MEASUREMENT.read(i2c, device_addr)
}
_ ->
state
end
{:noreply, updated_with_reading}
end
@impl true
def handle_call(:measure, _from, state) do
{:reply, {:ok, state.last_reading}, state}
end
end