Homex
Mix.install([
{:homex, github: "kevinschweikert/homex"},
# needed for ESPHome adapter
{:espex, "~> 0.9.0"},
# needed for ESPHome autodiscovery
{:muontrap, "~> 2.0"},
{:req, "~> 0.6.2"},
{:kino, "~> 0.19.0"},
])
Homex
Logger.configure(level: :info)
defmodule MySwitch do
use Homex.Entity.Switch, id: :relay, name: "Pump Relay"
def handle_on(entity) do
IO.puts("Relay turned on")
entity
end
def handle_off(entity) do
IO.puts("Relay turned off")
entity
end
end
defmodule MyTemperature do
use Homex.Entity.Sensor,
id: :bme280_temp,
name: "Outside Temperature",
unit_of_measurement: "°C",
device_class: "temperature"
def handle_init(entity) do
:timer.send_interval(10_000, :measure)
entity
end
def handle_info(:measure, entity) do
entity |> set_value(Enum.random(-40..40//1))
end
end
defmodule MyHumidity do
use Homex.Entity.Sensor,
id: :bme280_hum,
name: "Outside Humidity",
unit_of_measurement: "%",
device_class: "humidity"
def handle_init(entity) do
:timer.send_interval(10_000, :measure)
entity
end
def handle_info(:measure, entity) do
entity |> set_value(Enum.random(20..90//1))
end
end
defmodule MyButton do
use Homex.Entity.Button, id: :gpio17, name: "Open Door"
def handle_press(entity) do
IO.puts("my button was pressed")
entity
end
end
defmodule MyLight do
use Homex.Entity.Light, id: :ws2812, name: "Lava Lamp", modes: [:brightness]
def handle_init(entity) do
entity |> set_on() |> set_brightness(50)
end
def handle_brightness(entity, brightness) do
IO.puts("Light set to #{brightness}%")
entity
end
end
defmodule MyDevice do
use Homex.Entity.DeviceTrigger, id: :reed_switch, name: "Door Opened"
end
defmodule MyText do
use Homex.Entity.Text, id: :greeting, name: "Greeting"
def handle_init(entity), do: set_text(entity, "World")
def handle_text(entity, text) do
IO.puts("Hello #{text}")
entity
end
end
defmodule MyCamera do
use Homex.Entity.Camera, id: :ov2640, name: "Front Door Surveillance"
def handle_init(entity) do
:timer.send_interval(5_000, :snap)
entity
end
def handle_info(:snap, entity), do: snap(entity)
def handle_capture(entity), do: snap(entity)
defp snap(entity) do
%{body: image} = Req.get!("https://picsum.photos/200", redirect_log_level: false)
entity |> set_image(image) |> set_attributes(%{bytes: byte_size(image)})
end
end
{:ok, pid} =
Homex.start_link(
id: "livebook",
devices: [default: [name: "Livebook"]],
adapters: [{Homex.Adapter.ESPHome, mdns: :system}],
entities: [
MySwitch,
MyTemperature,
MyHumidity,
MyButton,
MyLight,
MyDevice,
MyCamera,
MyText
]
)
Dashboard
Let's have a look at our entities. Each card live updates when you change a value in Homeassistant and vice versa. Try it!
Homex.Livebook.new()
You can get the latest state of an entity with Homex.snapshot/1.
Homex.Entity.snapshot(:bme280_temp)
Adding entities at runtime
Entities don't have to be listed at start time. Homex.add_entity/1 and
Homex.add_entities/1 start an entity under the same supervision tree and
tell the adapters to republish, so it shows up right away without a restart.
defmodule MyNumber do
use Homex.Entity.Number, id: :brightness, name: "Brightness", min: 0, max: 100, step: 1
def handle_init(entity) do
%{brightness: brightness} = Entity.snapshot(:ws2812)
set_number(entity, brightness)
end
def handle_number(entity, number) do
Entity.send_command(:ws2812, %{brightness: number})
entity
end
end
defmodule MySelect do
use Homex.Entity.Select, id: :mode, name: "Mode", options: ["on", "off"]
def handle_init(entity) do
%{state: state} = Entity.snapshot(:ws2812)
set_option(entity, if(state, do: "on", else: "off"))
end
def handle_option(entity, "on") do
Entity.send_command(:ws2812, %{state: true})
entity
end
def handle_option(entity, "off") do
Entity.send_command(:ws2812, %{state: false})
entity
end
end
Homex.add_entities([MyNumber, MySelect])