9. Fledex: Job
Mix.install([
{:fledex, "~>0.5"},
{:jason, "~>1.2"}
])
Setup
Let’s start with the usual setup
use Fledex
Clock with job
In the last couple of examples it was always a bit cumbersome to get those updates in regular intervals. at every screen refresh we needed to do calculate something or we needed a decently complicated GenServer
to do tasks in regular intervals.
Let me introduce you to job
. It allows us to take care of repetitive work by easily specifying a cron-job. All you need are:
- a name for the job that identifies it uniquely
- a schedule when the job should run (see this cheatsheet for the possibilities)
-
and a function that should be executed, probably one that will at the end publish an event with
Fledex.Utils.PubSub.broadcast_trigger/1
The example here implements our clock example with the Fledex.Component.Clock
component (see the previous chapter) and uses the job
macro to schedule the updates.
alias Fledex.Component.Clock
led_strip :nested_components2, Kino do
component(
:clock,
Clock,
trigger_name: {:clock_hour, :clock_minute, :clock_second}
)
job :clock, ~e[@secondly]e do
date_time = DateTime.utc_now()
broadcast_trigger(%{
clock_hour: date_time.hour,
clock_minute: date_time.minute,
clock_second: date_time.second
})
end
end
Weather station with job
Our weather station example becomes now much easier, because we don’t have to implement the timer functinality ourselves. We can simply implement a job for that.
As before we need to make sure we can make http calls by starting the appropriate services
:inets.start()
:ssl.start()
Now we are ready to define our new simplified weather station using:
-
defining an
Fledex.led_strip
-
using the
Fledex.Component.Thermometer
component asFledex.component
-
and defining a
Fledex.job
that runs every 15min (making sure we call it as soon as we define it even though it might not be time for it yet, by specifyingrun_once: true
)
Note: we are using the normal crontab job pattern, whereas above we used the extended version (with second precision) above.
alias Fledex.Component.Thermometer
led_strip :john, Kin do
component(:thermo, Thermometer,
range: -20..40,
trigger: :temperature,
negative: :blue,
null: :may_green,
positive: :red,
marker: :davy_s_grey
)
job :fetcher, ~e[*/15 * * * * *], run_once: true do
url =
~c"https://api.open-meteo.com/v1/forecast?latitude=47.4729344&longitude=19.0468802¤t=temperature_2m"
{:ok, resp} =
:httpc.request(:get, {url, []}, [], body_format: :binary)
{{_, 200, ~c"OK"}, _headers, body} = resp
json = Jason.decode!(body)
temperature = json["current"]["temperature_2m"]
broadcast_trigger(%{temperature: temperature})
end
end