missing stuff ????

d84c4ce · gmorell · 2022-07-17 02:10

26 files +765 -2

Files changed

added apps/room_sanctum/lib/room_sanctum/storage/air_now/hourly_obs_data.ex
+107 −0
@@ -0,0 +1,107 @@
1 +defmodule RoomSanctum.Storage.AirNow.HourlyObsData do
2 + use Ecto.Schema
3 + import Ecto.Changeset
4 +
5 + schema "airnow_hourly_observations" do
6 + belongs_to :source, RoomSanctum.Configuration.Source
7 + field :pm10, :float
8 + field :valid_date, :date
9 + field :ozone_measured, :boolean, default: false
10 + field :country_code, :string
11 + field :ozone_aqi, :integer
12 + field :state_name, :string
13 + field :pm10_measured, :boolean, default: false
14 + field :gmt_offset, :float
15 + field :co_unit, :string
16 + field :point, Geo.PostGIS.Geometry
17 + field :so2, :float
18 + field :pm25, :float
19 + field :no2_aqi, :integer
20 + field :reporting_areas, {:array, :string}
21 + field :site_name, :string
22 + field :elevation, :float
23 + field :data_source, :string
24 + field :pm25_measured, :boolean, default: false
25 + field :so2_unit, :string
26 + field :valid_time, :time
27 + field :ozone_unit, :string
28 + field :lon, :float
29 + field :lat, :float
30 + field :epa_region, :string
31 + field :pm25_unit, :string
32 + field :ozone, :float
33 + field :aqsid, :string
34 + field :status, :string
35 + field :pm10_aqi, :integer
36 + field :no2_measured, :boolean, default: false
37 + field :pm10_unit, :string
38 + field :co, :float
39 + field :pm25_aqi, :integer
40 + field :no2, :float
41 + field :no2_unit, :string
42 +
43 + timestamps()
44 + end
45 +
46 + @doc false
47 + def changeset(hourly_obs_data, attrs) do
48 + hourly_obs_data
49 + |> cast(attrs, [
50 + :aqsid,
51 + :site_name,
52 + :status,
53 + :epa_region,
54 + :lat,
55 + :lon,
56 + :point,
57 + :elevation,
58 + :gmt_offset,
59 + :country_code,
60 + :state_name,
61 + :valid_date,
62 + :valid_time,
63 + :data_source,
64 + :reporting_areas,
65 + :ozone_aqi,
66 + :pm10_aqi,
67 + :pm25_aqi,
68 + :no2_aqi,
69 + :ozone_measured,
70 + :pm10_measured,
71 + :pm25_measured,
72 + :no2_measured,
73 + :no2,
74 + :no2_unit,
75 + :pm25,
76 + :pm25_unit,
77 + :ozone,
78 + :ozone_unit,
79 + :co,
80 + :co_unit,
81 + :so2,
82 + :so2_unit,
83 + :pm10,
84 + :pm10_unit,
85 + :source_id
86 + ])
87 + |> foreign_key_constraint(:source_id)
88 + |> validate_required([
89 + :aqsid,
90 + :site_name,
91 + :status,
92 + :lat,
93 + :lon,
94 + :point,
95 + :elevation,
96 + :state_name,
97 + :valid_date,
98 + :valid_time,
99 + :data_source,
100 + :reporting_areas,
101 + :ozone_measured,
102 + :pm10_measured,
103 + :pm25_measured,
104 + :no2_measured
105 + ])
106 + end
107 +end
added apps/room_sanctum/lib/room_sanctum/workers/vision_worker.ex
+37 −0
@@ -0,0 +1,37 @@
1 +defmodule RoomSanctum.Worker.Vision do
2 + @moduledoc false
3 + use GenServer
4 +
5 + require Logger
6 +
7 + alias RoomSanctum.Configuration
8 + alias RoomSanctum.Storage
9 + alias RoomSanctum.Repo
10 +
11 + @registry :zeus
12 +
13 + def start_link(opts) do
14 + GenServer.start_link(__MODULE__, opts, name: via_tuple("vision" <> opts[:id]))
15 + end
16 +
17 + def init(opts) do
18 + {:ok, %{id: opts[:id]}}
19 + end
20 +
21 + defp via_tuple(name), do: {:via, Registry, {@registry, name}}
22 +
23 + # Public
24 + def refresh_db_cfg(name) do
25 + "vision#{name}"
26 + |> via_tuple()
27 + |> GenServer.cast(:refresh_db_cfg)
28 + end
29 +
30 + def handle_cast(:refresh_db_cfg, state) do
31 + {:noreply, state}
32 + end
33 +
34 + def handle_cast(_msg, state) do
35 + {:noreply, state}
36 + end
37 +end
added apps/room_sanctum/lib/room_sanctum_web/live/hourly_obs_data_live/form_component.ex
+55 −0
@@ -0,0 +1,55 @@
1 +defmodule RoomSanctumWeb.HourlyObsDataLive.FormComponent do
2 + use RoomSanctumWeb, :live_component
3 +
4 + alias RoomSanctum.Storage.AirNow
5 +
6 + @impl true
7 + def update(%{hourly_obs_data: hourly_obs_data} = assigns, socket) do
8 + changeset = AirNow.change_hourly_obs_data(hourly_obs_data)
9 +
10 + {:ok,
11 + socket
12 + |> assign(assigns)
13 + |> assign(:changeset, changeset)}
14 + end
15 +
16 + @impl true
17 + def handle_event("validate", %{"hourly_obs_data" => hourly_obs_data_params}, socket) do
18 + changeset =
19 + socket.assigns.hourly_obs_data
20 + |> AirNow.change_hourly_obs_data(hourly_obs_data_params)
21 + |> Map.put(:action, :validate)
22 +
23 + {:noreply, assign(socket, :changeset, changeset)}
24 + end
25 +
26 + def handle_event("save", %{"hourly_obs_data" => hourly_obs_data_params}, socket) do
27 + save_hourly_obs_data(socket, socket.assigns.action, hourly_obs_data_params)
28 + end
29 +
30 + defp save_hourly_obs_data(socket, :edit, hourly_obs_data_params) do
31 + case AirNow.update_hourly_obs_data(socket.assigns.hourly_obs_data, hourly_obs_data_params) do
32 + {:ok, _hourly_obs_data} ->
33 + {:noreply,
34 + socket
35 + |> put_flash(:info, "Hourly obs data updated successfully")
36 + |> push_redirect(to: socket.assigns.return_to)}
37 +
38 + {:error, %Ecto.Changeset{} = changeset} ->
39 + {:noreply, assign(socket, :changeset, changeset)}
40 + end
41 + end
42 +
43 + defp save_hourly_obs_data(socket, :new, hourly_obs_data_params) do
44 + case AirNow.create_hourly_obs_data(hourly_obs_data_params) do
45 + {:ok, _hourly_obs_data} ->
46 + {:noreply,
47 + socket
48 + |> put_flash(:info, "Hourly obs data created successfully")
49 + |> push_redirect(to: socket.assigns.return_to)}
50 +
51 + {:error, %Ecto.Changeset{} = changeset} ->
52 + {:noreply, assign(socket, changeset: changeset)}
53 + end
54 + end
55 +end
added apps/room_sanctum/lib/room_sanctum_web/live/hourly_obs_data_live/form_component.html.heex
+148 −0
@@ -0,0 +1,148 @@
1 +<div>
2 + <h2><%= @title %></h2>
3 +
4 + <.form
5 + let={f}
6 + for={@changeset}
7 + id="hourly_obs_data-form"
8 + phx-target={@myself}
9 + phx-change="validate"
10 + phx-submit="save">
11 +
12 + <%= label f, :aqsid %>
13 + <%= text_input f, :aqsid %>
14 + <%= error_tag f, :aqsid %>
15 +
16 + <%= label f, :site_name %>
17 + <%= text_input f, :site_name %>
18 + <%= error_tag f, :site_name %>
19 +
20 + <%= label f, :status %>
21 + <%= text_input f, :status %>
22 + <%= error_tag f, :status %>
23 +
24 + <%= label f, :epa_region %>
25 + <%= text_input f, :epa_region %>
26 + <%= error_tag f, :epa_region %>
27 +
28 + <%= label f, :lat %>
29 + <%= number_input f, :lat, step: "any" %>
30 + <%= error_tag f, :lat %>
31 +
32 + <%= label f, :lon %>
33 + <%= number_input f, :lon, step: "any" %>
34 + <%= error_tag f, :lon %>
35 +
36 + <%= label f, :point %>
37 + <%= text_input f, :point %>
38 + <%= error_tag f, :point %>
39 +
40 + <%= label f, :elevation %>
41 + <%= number_input f, :elevation, step: "any" %>
42 + <%= error_tag f, :elevation %>
43 +
44 + <%= label f, :gmt_offset %>
45 + <%= number_input f, :gmt_offset %>
46 + <%= error_tag f, :gmt_offset %>
47 +
48 + <%= label f, :country_code %>
49 + <%= text_input f, :country_code %>
50 + <%= error_tag f, :country_code %>
51 +
52 + <%= label f, :state_name %>
53 + <%= text_input f, :state_name %>
54 + <%= error_tag f, :state_name %>
55 +
56 + <%= label f, :valid_date %>
57 + <%= date_select f, :valid_date %>
58 + <%= error_tag f, :valid_date %>
59 +
60 + <%= label f, :valid_time %>
61 + <%= time_select f, :valid_time %>
62 + <%= error_tag f, :valid_time %>
63 +
64 + <%= label f, :data_source %>
65 + <%= text_input f, :data_source %>
66 + <%= error_tag f, :data_source %>
67 +
68 + <%= label f, :reporting_areas %>
69 + <%= multiple_select f, :reporting_areas, ["Option 1": "option1", "Option 2": "option2"] %>
70 + <%= error_tag f, :reporting_areas %>
71 +
72 + <%= label f, :ozone_aqi %>
73 + <%= number_input f, :ozone_aqi %>
74 + <%= error_tag f, :ozone_aqi %>
75 +
76 + <%= label f, :pm10_aqi %>
77 + <%= number_input f, :pm10_aqi %>
78 + <%= error_tag f, :pm10_aqi %>
79 +
80 + <%= label f, :pm25_aqi %>
81 + <%= number_input f, :pm25_aqi %>
82 + <%= error_tag f, :pm25_aqi %>
83 +
84 + <%= label f, :no2_aqi %>
85 + <%= number_input f, :no2_aqi %>
86 + <%= error_tag f, :no2_aqi %>
87 +
88 + <%= label f, :ozone_measured %>
89 + <%= checkbox f, :ozone_measured %>
90 + <%= error_tag f, :ozone_measured %>
91 +
92 + <%= label f, :pm10_measured %>
93 + <%= checkbox f, :pm10_measured %>
94 + <%= error_tag f, :pm10_measured %>
95 +
96 + <%= label f, :pm25_measured %>
97 + <%= checkbox f, :pm25_measured %>
98 + <%= error_tag f, :pm25_measured %>
99 +
100 + <%= label f, :no2_measured %>
101 + <%= checkbox f, :no2_measured %>
102 + <%= error_tag f, :no2_measured %>
103 +
104 + <%= label f, :pm25 %>
105 + <%= number_input f, :pm25 %>
106 + <%= error_tag f, :pm25 %>
107 +
108 + <%= label f, :pm25_unit %>
109 + <%= text_input f, :pm25_unit %>
110 + <%= error_tag f, :pm25_unit %>
111 +
112 + <%= label f, :ozone %>
113 + <%= number_input f, :ozone %>
114 + <%= error_tag f, :ozone %>
115 +
116 + <%= label f, :ozone_unit %>
117 + <%= text_input f, :ozone_unit %>
118 + <%= error_tag f, :ozone_unit %>
119 +
120 + <%= label f, :co %>
121 + <%= number_input f, :co %>
122 + <%= error_tag f, :co %>
123 +
124 + <%= label f, :co_unit %>
125 + <%= text_input f, :co_unit %>
126 + <%= error_tag f, :co_unit %>
127 +
128 + <%= label f, :so2 %>
129 + <%= number_input f, :so2 %>
130 + <%= error_tag f, :so2 %>
131 +
132 + <%= label f, :so2_unit %>
133 + <%= text_input f, :so2_unit %>
134 + <%= error_tag f, :so2_unit %>
135 +
136 + <%= label f, :pm10 %>
137 + <%= number_input f, :pm10 %>
138 + <%= error_tag f, :pm10 %>
139 +
140 + <%= label f, :pm10_unit %>
141 + <%= text_input f, :pm10_unit %>
142 + <%= error_tag f, :pm10_unit %>
143 +
144 + <div>
145 + <%= submit "Save", phx_disable_with: "Saving..." %>
146 + </div>
147 + </.form>
148 +</div>
added apps/room_sanctum/lib/room_sanctum_web/live/hourly_obs_data_live/index.ex
+46 −0
@@ -0,0 +1,46 @@
1 +defmodule RoomSanctumWeb.HourlyObsDataLive.Index do
2 + use RoomSanctumWeb, :live_view
3 +
4 + alias RoomSanctum.Storage.AirNow
5 + alias RoomSanctum.Storage.AirNow.HourlyObsData
6 +
7 + @impl true
8 + def mount(_params, _session, socket) do
9 + {:ok, assign(socket, :hourly_observations, list_hourly_observations())}
10 + end
11 +
12 + @impl true
13 + def handle_params(params, _url, socket) do
14 + {:noreply, apply_action(socket, socket.assigns.live_action, params)}
15 + end
16 +
17 + defp apply_action(socket, :edit, %{"id" => id}) do
18 + socket
19 + |> assign(:page_title, "Edit Hourly obs data")
20 + |> assign(:hourly_obs_data, AirNow.get_hourly_obs_data!(id))
21 + end
22 +
23 + defp apply_action(socket, :new, _params) do
24 + socket
25 + |> assign(:page_title, "New Hourly obs data")
26 + |> assign(:hourly_obs_data, %HourlyObsData{})
27 + end
28 +
29 + defp apply_action(socket, :index, _params) do
30 + socket
31 + |> assign(:page_title, "Listing Hourly observations")
32 + |> assign(:hourly_obs_data, nil)
33 + end
34 +
35 + @impl true
36 + def handle_event("delete", %{"id" => id}, socket) do
37 + hourly_obs_data = AirNow.get_hourly_obs_data!(id)
38 + {:ok, _} = AirNow.delete_hourly_obs_data(hourly_obs_data)
39 +
40 + {:noreply, assign(socket, :hourly_observations, list_hourly_observations())}
41 + end
42 +
43 + defp list_hourly_observations do
44 + AirNow.list_hourly_observations()
45 + end
46 +end
added apps/room_sanctum/lib/room_sanctum_web/live/hourly_obs_data_live/index.html.heex
+103 −0

Click to load diff…

added apps/room_sanctum/lib/room_sanctum_web/live/hourly_obs_data_live/show.ex
+21 −0

Click to load diff…

added apps/room_sanctum/lib/room_sanctum_web/live/hourly_obs_data_live/show.html.heex
+186 −0

Click to load diff…

modified apps/room_zeus/lib/application.ex
+2 −1

Click to load diff…

added apps/room_zeus/lib/supervision_vision.ex
+30 −0

Click to load diff…

renamed apps/room_zeus/lib/supervision.ex → apps/room_zeus/lib/supervision_worker.ex
+1 −1

Click to load diff…

added assets/package-lock.json
+24 −0

Click to load diff…

added assets/package.json
+5 −0

Click to load diff…

Parents: 05f9c3d