Skip to content

Commit

Permalink
Show CPU temperature on MOTD
Browse files Browse the repository at this point in the history
  • Loading branch information
mnishiguchi committed Oct 26, 2022
1 parent 617d590 commit 6211d39
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
14 changes: 14 additions & 0 deletions lib/nerves_motd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ defmodule NervesMOTD do
[
[{"Uptime", uptime()}],
[{"Clock", Utils.formatted_local_time()}],
temperature_row(),
[],
[firmware_cell(), applications_cell(apps)],
[memory_usage_cell(), active_application_partition_cell()],
Expand All @@ -108,6 +109,19 @@ defmodule NervesMOTD do
[" ", format_cell(col0, 0), format_cell(col1, 1), "\n"]
end

defp format_row(nil), do: []

@spec temperature_row() :: [cell()] | nil
defp temperature_row() do
case runtime_mod().cpu_temperature() do
{:ok, temperature_c} ->
[{"Temperature", :erlang.float_to_binary(temperature_c, decimals: 1)}]

_ ->
nil
end
end

@spec format_cell(cell(), 0 | 1) :: IO.ANSI.ansidata()
defp format_cell({label, value}, column_index) do
[format_cell_label(label), " : ", format_cell_value(value, column_index, 24), :reset]
Expand Down
16 changes: 16 additions & 0 deletions lib/nerves_motd/runtime.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
defmodule NervesMOTD.Runtime do
@moduledoc false
@callback applications() :: %{started: [atom()], loaded: [atom()]}
@callback cpu_temperature() :: {:ok, float()} | :error
@callback firmware_valid?() :: boolean()
@callback load_average() :: [String.t()]
@callback memory_stats() ::
Expand Down Expand Up @@ -33,6 +34,21 @@ defmodule NervesMOTD.Runtime.Target do
%{started: started, loaded: loaded}
end

@impl NervesMOTD.Runtime
def cpu_temperature() do
# Read the file /sys/class/thermal/thermal_zone0/temp. The file content is
# an integer in millidegree Celsius, which looks like:
#
# 39008\n

with {:ok, content} <- File.read("/sys/class/thermal/thermal_zone0/temp"),
{millidegree_c, _} <- Integer.parse(content) do
{:ok, millidegree_c / 1000}
else
_error -> :error
end
end

@impl NervesMOTD.Runtime
def firmware_valid?() do
Nerves.Runtime.firmware_valid?()
Expand Down
16 changes: 16 additions & 0 deletions test/nerves_motd_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,22 @@ defmodule NervesMOTDTest do
assert capture_motd() =~ ~r/Clock : \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \w{3}/
end

test "Temperature when available" do
NervesMOTD.MockRuntime
|> Mox.expect(:applications, 1, default_applications_code())
|> Mox.expect(:cpu_temperature, 1, fn -> {:ok, 41.234} end)

assert capture_motd() =~ ~r/Temperature : 41.2/
end

test "Temperature when unavailable" do
NervesMOTD.MockRuntime
|> Mox.expect(:applications, 1, default_applications_code())
|> Mox.expect(:cpu_temperature, 1, fn -> :error end)

refute capture_motd() =~ ~r/Temperature/
end

test "Firmware when valid" do
NervesMOTD.MockRuntime
|> Mox.expect(:applications, 1, default_applications_code())
Expand Down
3 changes: 3 additions & 0 deletions test/support/runtime.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ defmodule NervesMOTD.Runtime.Host do
@impl NervesMOTD.Runtime
def applications(), do: %{loaded: @apps, started: @apps}

@impl NervesMOTD.Runtime
def cpu_temperature(), do: {:ok, 41.234}

@impl NervesMOTD.Runtime
def firmware_valid?(), do: true

Expand Down

0 comments on commit 6211d39

Please sign in to comment.