<!--
Copyright 2024-2025, Matthias Reik <fledex@reik.org>
SPDX-License-Identifier: Apache-2.0
-->
# 9. Fledex: Job
```elixir
Mix.install([
{:fledex, "~>0.7"},
{:jason, "~>1.2"}
])
```
## Setup
Let's start with the usual setup
```elixir
use Fledex
```
<!-- livebook:{"branch_parent_index":0} -->
## Clock with job
In the last couple of examples it was always a bit cumbersome to get those updates in regular intervals. Either we had to calculate at every screen refresh, or created a decently complicated `GenServer` to do tasks in regular intervals. As we have seen in the [last example](8_fledex_component.livemd) there is an easier way to do this by using the `job` macro.
Let me now introduce you properly to the `job` macro. 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](https://hexdocs.pm/crontab/cron_notation.html#expressions) 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.
```elixir
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
```
<!-- livebook:{"branch_parent_index":0} -->
## 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
```elixir
: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 as `Fledex.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 specifying `run_once: true`)
> #### Note
>
> We are using the normal crontab job pattern, whereas above we used the extended version
> (with second precision), indicated by the extra trailing `e`.
```elixir
alias Fledex.Component.Thermometer
led_strip :john, Kino 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
```