We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Post 64
Weather App 11 - Normalization/Supervisor Tree
Published on: 2025-08-25
Tags:
elixir, Blog, Side Project, Libraries, Nerves, Weather App, Poncho
Include Dependencies for Sensors
Okay so we are not starting to normalize the data from the sensors. We will do this with the file /sensor_hub/sensor.ex.
sensor.ex
defstruct [:name, :fields, :read, :convert]
def new(name) do
%__MODULE__{
read: read_fn(name),
convert: convert_fn(name),
fields: fields(name),
name: name
}
end
#then we need fields(), read(), convert()
def fields(SPG40), do: [:voc_index]
def read(SPG40), do: fn -> Sgp40.get_measurement() end
def convert_fn(SGP40) do
fn reading ->
Map.take(reading, [:voc_index])
end
end
With these for each sensor we are now passing the GenServer by name to the new that will start to take measurements from each sensor and turn the general values into something that we can use for each sensor.
Here are some lines to put into iex so you can test everything:
alias SensorHub.Sensor
Bme280.start_link()
Sgp40.start_link()
TSL25911FN.start_link()
LTR390_UV.start_link()
bme = Sensor.new(Bme280)
sgp = Sensor.new(Sgp40)
tsl = Sensor.new(TSL25911FN)
ltr = Sensor.new(LTR390_UV)
Sensor.measure(bme)
Sensor.measure(sgp)
Sensor.measure(tsl)
Sensor.measure(ltr)
To go over a few things the code sinpets above are set to work when the readings give you the exact keys in the map as the fields. I had to do some work to make what I have work as most all the readings will return something like %{last_reading: last_reading} with last_reading having some reference to the values that it will have in it.
Setting up the Supervisor tree
We now need to be sure that not only is there a supervisor tree setup to make sure that you have a way to make sure that the GenSevers will restart and all start in the correct order we also need to be sure that we auto start the sensors when we power the Raspberry Pi
def children(_target) do
# This function returns the child processes to be supervised
# Here you can define the children for your application
[
{Bme280, []},
{Sgp40, []},
{TSL25911FN, []},
{LTR390_UV, []}
]
end
and
@impl true
def start(_type, _args) do
# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
children =
children(target())
opts = [strategy: :one_for_one, name: SensorHub.Supervisor]
Supervisor.start_link(children, opts)
end
Now we can create and upload the firmware and it will start automatically and also we can test the sensors with
Supervisor.which_children(SensorHub.Supervisor)
Bme280 |> Sensor.new() |> Sensor.measure()
This is everything that we wanted to deal with up to this point. Next we can deal with some offset for the temp and VOC and then PUBLISHING THE SENSOR DATA.