defmodule AugieWeb.PowerSensorLive do use Phoenix.LiveView alias Augie.DataFlow alias Augie.Sensor.Power @moduledoc """ A LiveView which displays the data from the Power sensor. """ @sample_count 60 def render(assigns) do ~L"""

Power Sensor

<%= if @data_ready do %>
Bus Voltage
<%= Float.round(@avg_bus_voltage, 2) %>V
<%= live_component(@socket, AugieWeb.SparklineComponent, data: @bus_voltage, min: 0, sample_count: 60) %>
Shunt Voltage
<%= Float.round(@avg_shunt_voltage, 2) %>V
<%= live_component(@socket, AugieWeb.SparklineComponent, data: @shunt_voltage, min: 0, sample_count: 60) %>
Current
<%= Float.round(@avg_current, 2) %>mA
<%= live_component(@socket, AugieWeb.SparklineComponent, data: @current, min: 0, sample_count: 60) %>
Power
<%= Float.round(@avg_power, 2) %>mW
<%= live_component(@socket, AugieWeb.SparklineComponent, data: @power, min: 0, sample_count: 60) %>
<% else %>
No data available.
<% end %>
""" end def mount(_params, _context, socket) do if connected?(socket), do: DataFlow.subscribe(Power) socket = socket |> assign( data_ready: false, bus_voltage: CircularBuffer.new(@sample_count), shunt_voltage: CircularBuffer.new(@sample_count), current: CircularBuffer.new(@sample_count), power: CircularBuffer.new(@sample_count), avg_bus_voltage: 0, avg_shunt_voltage: 0, avg_current: 0, avg_power: 0 ) {:ok, socket} end def handle_info( {DataFlow, Power, sample}, %{ assigns: %{ bus_voltage: bus_voltage, shunt_voltage: shunt_voltage, current: current, power: power } } = socket ) do bus_voltage = bus_voltage |> CircularBuffer.insert(abs(sample.bus_voltage)) shunt_voltage = shunt_voltage |> CircularBuffer.insert(abs(sample.shunt_voltage)) current = current |> CircularBuffer.insert(abs(sample.current)) power = power |> CircularBuffer.insert(abs(sample.power)) avg_bus_voltage = avg(bus_voltage) avg_shunt_voltage = avg(shunt_voltage) avg_current = avg(current) avg_power = avg(power) socket = socket |> assign( data_ready: true, bus_voltage: bus_voltage, shunt_voltage: shunt_voltage, current: current, power: power, avg_bus_voltage: avg_bus_voltage, avg_shunt_voltage: avg_shunt_voltage, avg_current: avg_current, avg_power: avg_power ) {:noreply, socket} end defp avg(buffer) do count = Enum.count(buffer) sum = Enum.sum(buffer) sum / count end end