machine and links working now, cleaned UI and ported afterdark over

962e964 · gmorell · 2022-12-12 06:08

31 files +488 -88

Files changed

modified assets/tailwind.config.js
+17 −0
@@ -4,6 +4,23 @@
4 4 const plugin = require("tailwindcss/plugin")
5 5
6 6 module.exports = {
7 + daisyui: {
8 + themes: [
9 + {
10 + afterdark: {
11 + "primary": "#7B79B5",
12 + "secondary": "#ACABD5",
13 + "accent": "#fef3c7",
14 + "neutral": "#38357F",
15 + "base-100": "#201D65",
16 + "info": "#7dd3fc",
17 + "success": "#a7f3d0",
18 + "warning": "#fef08a",
19 + "error": "#fca5a5",
20 + },
21 + },
22 + ]
23 + },
7 24 content: [
8 25 "./js/**/*.js",
9 26 "../lib/*_web.ex",
modified lib/lambent_ex/link.ex
+35 −35
@@ -4,58 +4,58 @@ defmodule LambentEx.Link do
4 4
5 5 @pubsub_name LambentEx.PubSub
6 6 @pubsub_topic "machine-"
7 + @pubsub_topic_idx "links_idx"
7 8
8 − @registry :lambent
9 + @registry :lambent_links
9 10
10 11 def start_link(opts) do
11 12 GenServer.start_link(__MODULE__, opts, name: via_tuple("link-#{opts[:name]}"))
12 13 end
13 14
14 − def init(_opts) do
15 − Phoenix.PubSub.subscribe(@pubsub_name, @pubsub_topic)
15 + def init(opts) do
16 + Process.send_after(self(), :publish, 50)
17 + {:ok, opts} = Keyword.validate(opts, [:source, :target, :name])
18 + Phoenix.PubSub.subscribe(@pubsub_name, @pubsub_topic <> opts[:source])
19 +
20 + # todo
21 + # publish-pause-siblings
22 + # subscribe-pause-siblings
16 23
17 − # gets overwritten
18 24 {
19 25 :ok,
20 − %{}
26 + %{
27 + source: opts[:source],
28 + target: opts[:target],
29 + name: opts[:name],
30 + enabled: true,
31 + }
21 32 }
22 33 end
23 34
24 35 defp via_tuple(name), do: {:via, Registry, {@registry, name}}
25 36
37 + defp publish(state) do
38 + %{
39 + name: state[:name],
40 + source: state[:source],
41 + target: state[:target],
42 + enabled: state[:enabled]
43 + }
44 + end
45 +
26 46 def handle_info({:publish, data}, state) do
27 − IO.puts("hhh")
28 −
29 − dvcs =
30 − [
31 − {192, 168, 13, 203},
32 − {192, 168, 13, 209},
33 − {192, 168, 13, 211},
34 − {192, 168, 13, 214},
35 − {192, 168, 13, 215},
36 − {192, 168, 13, 222},
37 − {192, 168, 13, 225},
38 − {192, 168, 13, 228},
39 − {192, 168, 13, 230},
40 − {192, 168, 13, 241}
41 − ]
42 −
43 − dvcs = [
44 − "10:52:1c:02:8c:12",
45 − "10:52:1c:02:d4:d2",
46 − "18:fe:34:d4:7a:b5",
47 − "68:c6:3a:a4:d3:b6",
48 − "8c:aa:b5:1b:46:09",
49 − "a4:cf:12:b3:fc:b6",
50 − "ec:fa:bc:c0:96:98",
51 −
52 − ]
53 −
54 − for i <- dvcs do
55 − LambentEx.Scan.ESP8266x7777.submit(i, data |> List.flatten)
47 + case state[:enabled] do
48 + true -> LambentEx.Scan.ESP8266x7777.submit(state[:target], data |> List.flatten)
49 + false -> :ok
56 50 end
57 − # IO.inspect(data)
58 51
59 52 {:noreply, state}
60 53 end
54 +
55 + @impl true
56 + def handle_info(:publish, state) do
57 + Process.send_after(self(), :publish, 400)
58 + Phoenix.PubSub.broadcast(@pubsub_name, @pubsub_topic_idx, {:publish, publish(state)})
59 + {:noreply, state}
60 + end
61 61 end
modified lib/lambent_ex/machine.ex
+39 −6
@@ -6,6 +6,7 @@ defmodule LambentEx.Machine do
6 6
7 7 @pubsub_name LambentEx.PubSub
8 8 @pubsub_topic "machine-"
9 + @pubsub_topic_idx "machines_idx"
9 10
10 11 @speeds %{
11 12 # 1 => :THOU,
@@ -42,6 +43,7 @@ defmodule LambentEx.Machine do
42 43
43 44 def init(opts) do
44 45 Process.send_after(self(), :step, 100)
46 + Process.send_after(self(), :publish, 50)
45 47 {:ok, opts} = Keyword.validate(opts, [:step, :step_opts, :name, count: 300])
46 48 cnt = opts[:count]
47 49
@@ -62,6 +64,7 @@ defmodule LambentEx.Machine do
62 64
63 65 {:ok,
64 66 %{
67 + step: opts[:step],
65 68 steps: pids,
66 69 name: opts[:name],
67 70 # todo configurable
@@ -97,7 +100,28 @@ defmodule LambentEx.Machine do
97 100 # impls
98 101
99 102 defp bmath(i, state) do
100 − (i * state.bright_curr / 255.0) |> trunc
103 + (i * state.bright_curr / 255.0) |> round
104 + end
105 +
106 + def stripstep(step) do
107 + [_head, step] = step |> to_string |> String.split(".Steps.")
108 + step
109 + end
110 +
111 + defp id(state) do
112 + step = state[:step] |> stripstep
113 + [step, "x", state[:name]] |> Enum.join("")
114 + end
115 +
116 + defp publish(state) do
117 + %{
118 + id: id(state),
119 + name: state[:name],
120 + step: state[:step] |> stripstep,
121 + speed: state[:speed],
122 + cnt: state[:cnt],
123 + bgt: state[:bright_curr]
124 + }
101 125 end
102 126
103 127 @impl true
@@ -107,15 +131,24 @@ defmodule LambentEx.Machine do
107 131 state[:steps]
108 132 |> Enum.map(&GenServer.cast(&1, :step))
109 133
110 − data = state[:steps]
111 − |> Enum.map(&GenServer.call(&1, :read))
112 − |> Enum.map(fn x -> x |> Enum.map(fn y -> bmath(y, state) end) end)
113 −#
114 −# |> IO.inspect()
134 + data =
135 + state[:steps]
136 + |> Enum.map(&GenServer.call(&1, :read))
137 + |> Enum.map(fn x -> x |> Enum.map(fn y -> bmath(y, state) end) end)
138 +
139 + #
140 + # |> IO.inspect()
115 141 Phoenix.PubSub.broadcast(@pubsub_name, @pubsub_topic <> state[:name], {:publish, data})
116 142 {:noreply, bright_step(state)}
117 143 end
118 144
145 + @impl true
146 + def handle_info(:publish, state) do
147 + Process.send_after(self(), :publish, 400)
148 + Phoenix.PubSub.broadcast(@pubsub_name, @pubsub_topic_idx, {:publish, publish(state)})
149 + {:noreply, state}
150 + end
151 +
119 152 def handle_info({:EXIT, pid, err}, state) do
120 153 IO.inspect(err)
121 154 {:noreply, state}
modified lib/lambent_ex/scan/8266-7777.ex
+68 −29
@@ -4,6 +4,7 @@ defmodule LambentEx.Scan.ESP8266x7777 do
4 4 require Logger
5 5
6 6 alias LambentEx.Utils.Color, as: C
7 + alias LambentEx.Meta, as: M
7 8
8 9 @registry :lambent
9 10 @s "ꙭ📡"
@@ -25,13 +26,7 @@ defmodule LambentEx.Scan.ESP8266x7777 do
25 26 %{
26 27 interfaces: interfaces,
27 28 arps: %{},
28 − devices: %{
29 − "10:52:1c:02:d4:d2" => %{
30 − "ip" => {192, 168, 13, 226},
31 − "name" => "AssFace3k",
32 − "ord" => :rgb
33 − }
34 − },
29 + devices: %{},
35 30 socket: socket
36 31 }}
37 32 end
@@ -56,6 +51,10 @@ defmodule LambentEx.Scan.ESP8266x7777 do
56 51 via_tuple("scan_8266") |> GenServer.cast({:submit, dvc, stream})
57 52 end
58 53
54 + def poke(dvc) do
55 + via_tuple("scan_8266") |> GenServer.cast({:poke, dvc})
56 + end
57 +
59 58 def devices() do
60 59 via_tuple("scan_8266") |> GenServer.call(:get_devices)
61 60 end
@@ -66,14 +65,24 @@ defmodule LambentEx.Scan.ESP8266x7777 do
66 65 def handle_cast({:rename_mac, mac, name}, state) do
67 66 d = state[:devices] |> Map.get(mac)
68 67 dev = state[:devices] |> Map.put(mac, d |> Map.put("name", name))
68 + # write to ets
69 + M.put_name(mac, name)
69 70 {:noreply, %{state | devices: dev}}
70 71 end
71 72
72 73 @impl true
73 74 def handle_cast({:rename_ip, ip, name}, state) do
74 − mac = state[:arps] |> Enum.map(fn {iface, arr} -> arr |> Enum.map(fn {k,v} -> {k,v} end) end) |> List.flatten |> Map.new |> Map.get(ip)
75 + mac =
76 + state[:arps]
77 + |> Enum.map(fn {iface, arr} -> arr |> Enum.map(fn {k, v} -> {k, v} end) end)
78 + |> List.flatten()
79 + |> Map.new()
80 + |> Map.get(ip)
81 +
75 82 d = state[:devices] |> Map.get(mac)
76 83 dvcs = state[:devices] |> Map.put(mac, d |> Map.put("name", name))
84 +
85 + M.put_name(mac, name)
77 86 {:noreply, %{state | devices: dvcs}}
78 87 end
79 88
@@ -81,17 +90,15 @@ defmodule LambentEx.Scan.ESP8266x7777 do
81 90 def handle_cast({:reorder, mac, ord}, state) do
82 91 d = state[:devices] |> Map.get(mac)
83 92 dev = state[:devices] |> Map.put(mac, d |> Map.put("ord", ord))
93 +
94 + M.put_ord(mac, ord)
84 95 {:noreply, %{state | devices: dev}}
85 96 end
86 97
87 98 @impl true
88 99 def handle_cast({:submit, dvc, stream}, state) do
89 − IO.inspect(state[:devices])
90 − IO.inspect(dvc)
91 −
92 100 case state[:devices] |> Map.get(dvc) do
93 101 nil ->
94 − IO.inspect(:nd)
95 102 {:noreply, state}
96 103
97 104 device ->
@@ -100,6 +107,23 @@ defmodule LambentEx.Scan.ESP8266x7777 do
100 107 end
101 108 end
102 109
110 + @impl true
111 + def handle_cast({:poke, dvc}, state) do
112 + case state[:devices] |> Map.get(dvc) do
113 + nil ->
114 + {:noreply, state}
115 +
116 + device ->
117 + for {i,c} <- [{10, C.cre}, {100, C.cbe}, {200, C.cge}, {300, C.cce}, {400, C.cye}, {500, C.cme}, {600, C.cke}] do
118 + Process.send_after(self(), {:send, device, c}, i)
119 + end
120 + {:noreply, state}
121 + end
122 +
123 + {:noreply, state}
124 + end
125 +
126 + @impl true
103 127 def handle_call(:get_devices, _from, state) do
104 128 {:reply, state[:devices], state}
105 129 end
@@ -130,28 +154,28 @@ defmodule LambentEx.Scan.ESP8266x7777 do
130 154
131 155 case device |> Map.get(:ord) do
132 156 :rgb ->
133 − chunked
157 + chunked |> Enum.map(fn [r, g, b] -> [g,r,b] end)
134 158
135 159 :grb ->
136 − chunked |> Enum.map(fn [r, g, b] -> [g, r, b] end)
160 + chunked |> Enum.map(fn [r, g, b] -> [r, g, b] end)
137 161
138 162 :rgbww ->
139 − chunked |> Enum.map(fn [r, g, b] -> [r, g, b, Enum.min(C.wrgb([r, g, b]), r)] end)
163 + chunked |> Enum.map(fn [r, g, b] -> [g,r,b, Enum.min(C.wrgb([r, g, b]), r)] end)
140 164
141 165 :rgbnw ->
142 − chunked |> Enum.map(fn [r, g, b] -> [r, g, b, C.wrgb([r, g, b])] end)
166 + chunked |> Enum.map(fn [r, g, b] -> [g,r,b, C.wrgb([r, g, b])] end)
143 167
144 168 :rgbcw ->
145 − chunked |> Enum.map(fn [r, g, b] -> [r, g, b, Enum.min([C.wrgb([r, g, b]), b])] end)
169 + chunked |> Enum.map(fn [r, g, b] -> [g,r,b, Enum.min([C.wrgb([r, g, b]), b])] end)
146 170
147 171 :rgbaw ->
148 − chunked |> Enum.map(fn [r, g, b] -> [r, g, b, C.argb([r, g, b]), C.wrgb([r, g, b])] end)
172 + chunked |> Enum.map(fn [r, g, b] -> [g,r,b, C.argb([r, g, b]), C.wrgb([r, g, b])] end)
149 173
150 174 :rgbxw ->
151 − chunked |> Enum.map(fn [r, g, b] -> [r, g, b, 0] end)
175 + chunked |> Enum.map(fn [r, g, b] -> [g,r,b, 0] end)
152 176
153 177 nil ->
154 − chunked
178 + chunked |> Enum.map(fn [r, g, b] -> [g,r,b] end)
155 179 end
156 180 |> List.flatten()
157 181 end
@@ -161,8 +185,6 @@ defmodule LambentEx.Scan.ESP8266x7777 do
161 185 stream
162 186 end
163 187
164 −
165 −
166 188 @impl true
167 189 def handle_call(_msg, _from, state) do
168 190 {:reply, :ok, state}
@@ -243,24 +265,38 @@ defmodule LambentEx.Scan.ESP8266x7777 do
243 265 {:noreply, state}
244 266 end
245 267
268 + def handle_info({:send, dvc, stream}, state) do
269 +
270 + :gen_udp.send(state.socket, dvc["ip"], 7777, rgb_shift(stream, dvc) |> rgb_stream)
271 + {:noreply, state}
272 + end
273 +
246 274 defp add_type(devices) do
247 − devices |> Enum.map(fn {k,v} -> {k, v |> Map.put("type", "8266-7777")} end) |> Map.new
275 + devices |> Enum.map(fn {k, v} -> {k, v |> Map.put("type", "8266-7777")} end) |> Map.new()
248 276 end
249 277
250 278 @impl true
251 279 def handle_info(:publish, state) do
252 280 Process.send_after(self(), :publish, :timer.seconds(2))
253 − Phoenix.PubSub.broadcast(@pubsub_name, "scan-82667777", {:publish, state[:devices] |> add_type})
281 +
282 + Phoenix.PubSub.broadcast(
283 + @pubsub_name,
284 + "scan-82667777",
285 + {:publish, state[:devices] |> add_type}
286 + )
287 +
254 288 {:noreply, state}
255 289 end
256 290
257 −
258 291 defp join_arps(new, state) do
259 292 arps = state[:arps]
260 293
261 − result = arps |> Map.merge(new, fn _k, v1, v2 ->
262 − v1 |> Map.merge(v2)
263 − end)
294 + result =
295 + arps
296 + |> Map.merge(new, fn _k, v1, v2 ->
297 + v1 |> Map.merge(v2)
298 + end)
299 +
264 300 %{state | arps: result}
265 301 end
266 302
@@ -281,8 +317,11 @@ defmodule LambentEx.Scan.ESP8266x7777 do
281 317 |> Enum.reduce(fn x, y ->
282 318 Map.merge(x, y, fn _k, v1, v2 -> v2 ++ v1 end)
283 319 end)
320 + |> Enum.map(fn {k,v} -> {k, v |> Map.put("name", M.get_name(k)) |> Map.put("ord", M.get_ord(k))}end)
321 + |> Enum.filter(fn {k, _v} -> k != nil end)
322 + |> Map.new
284 323
285 − state |> Map.put(:devices, rez)
324 + state |> Map.put(:devices, Map.merge(devices, rez))
286 325 end
287 326
288 327 def get_valid_interfaces() do
added lib/lambent_ex/scan/meta.ex
+43 −0
@@ -0,0 +1,43 @@
1 +defmodule LambentEx.Meta do
2 + use GenServer
3 +
4 + @table :lex_metadata
5 +
6 + def init(arg) do
7 + {:ok, table} = :dets.open_file(@table, [type: :set])
8 +
9 + {:ok, %{table: table}}
10 + end
11 +
12 + def start_link(arg) do
13 + GenServer.start_link(__MODULE__, arg, name: __MODULE__)
14 + end
15 +
16 + def get_name(mac) do
17 + case :dets.lookup(@table, "name-#{mac}") do
18 + [] ->
19 + nil
20 +
21 + [{_key, value}] ->
22 + value
23 + end
24 + end
25 +
26 + def get_ord(mac) do
27 + case :dets.lookup(@table, "ord-#{mac}") do
28 + [] ->
29 + nil
30 +
31 + [{_key, value}] ->
32 + value
33 + end
34 + end
35 +
36 + def put_name(key, value) do
37 + :dets.insert(@table, {"name-#{key}", value})
38 + end
39 +
40 + def put_ord(key, value) do
41 + :dets.insert(@table, {"ord-#{key}", value})
42 + end
43 +end
modified lib/lambent_ex/supervision/component.ex
+2 −0

Click to load diff…

added lib/lambent_ex/supervision/link.ex
+24 −0

Click to load diff…

modified lib/lambent_ex/util/color.ex
+16 −0

Click to load diff…

modified lib/lambent_ex_web/components/layouts/app.html.heex
+39 −5

Click to load diff…

modified lib/lambent_ex_web/components/layouts/root.html.heex
+2 −2

Click to load diff…

modified lib/lambent_ex_web/live/devices/index.ex
+11 −8

Click to load diff…

modified lib/lambent_ex_web/live/devices/index.html.heex
+1 −1

Click to load diff…

modified ?
+0 −0

Click to load diff…

added lib/lambent_ex_web/live/links/index.ex
+38 −0

Click to load diff…

added lib/lambent_ex_web/live/links/index.html.heex
+30 −0

Click to load diff…

added lib/lambent_ex_web/live/machines/index.ex
+78 −0

Click to load diff…

added lib/lambent_ex_web/live/machines/index.html.heex
+41 −0

Click to load diff…

modified lib/lambent_ex_web/router.ex
+4 −2

Click to load diff…

Parents: 1296a60