Horus is my first project concerning connected devices and smart home. It takes the form of an API which communicates with connected LIFX lights bulbs in a local network.
An observation: there are more and more connected devices. They take different forms such as lights, thermostat, smart TV, security camera, smoke detectors… These devices make what a smart home is: a house full of automation where pressing a switch is totally useless. Everybody can easily say, in a near future, that a house without any automation will be comparable to a house without running water at the end of the last century (in a rich country).
I wanted to know more about these devices and I decided to work on my own to get a better understanding of these strange devices. At the beginning of the year, I bought a connected light to LIFX. Why did I choose this vendor? They have devices with which we can interact in LAN, completely disconnected by the rest of the internet (well, “completely”? no, we need to connect our light to the cloud to connect that to our internet box).
After having fun with the LIFX application, I decided to try to send some UDP packets to my light bulb without the help of the LIFX cloud. I saw that is was a little bit complex, especially to turn on a light. I decided to make it easier.
Here is Horus
A the time of writing, the Horus version is
To communicate with LIFX devices in a local network, it uses the UDP protocol. This uses a simple connectionless communication model with a minimum of protocol mechanism.
LIFX gives us complete documentation of LAN communication you can find here.
Well, here we are, writing UDP packets full of bytes. It is not really human-friendly, hum? That is why I created Horus.
Horus is an API which manages LIFX devices connected to a local network. This application has been written in Go and uses Docker to be executed. It uses UDP protocol to send packets to the selected devices you want to interact with.
Currently, it owns 3 routes protected by an API key:
/lights?key=&selector=: returns a list of lights corresponding to the selector.
/lights/state?key=&selector=: sets a new state to selected lights.
/lights/toggle?key=&selector=: toggles the current power state of selected lights.
Note that you can find the complete API documentation here.
How do selector work? The selector system was largely inspired by the LIFX system.
Let’s use it!
Let’s take a look to the
# apiKey is a key to use your protected API paths such as /lights. # Must be a valid version 4 UUID. # Generate a new UUID here: https://www.uuidgenerator.net/version4 apiKey: 086bf714-7d7f-4f1c-a195-ba2809827374 # source is the unique identifier for the client. # Must be positive, between 0 and 2,147,483,647. source: 437 # domain is the network where all your lifx devices are connected. # Must be written with the CIRD form (ex: `192.168.1.0/24 for a local network) domain: 192.168.1.0/24 # maxBrightness is the default brightness value. # This value is used when you toggle a device (/lights/toggle). # Must be positive, between 0 and 65535. maxBrightness: 65535 # lifx is a collection containing your Lifx devices. # Initiliaze it by just adding their informations. # ex: # lifx: # - uuid: 33d07008-2082-4d7f-82f3-04c275b70055 # address: 192.168.1.22 # port: "56700" # protocol: "udp" # - uuid: add99b6c-ce82-452f-bbf7-a9bf32f3aa15 # address: 192.168.1.15 # port: "56700" # protocol: "udp" lifx: - uuid: 33d07008-2082-4d7f-82f3-04c275b70055 address: 192.168.1.22 port: "56700" protocol: "udp"
$ docker-compose up -d
It downloads the latest version of the Docker image and runs this one in a container on the port
Here is a list of possible improvements:
- Complete documentation for “usages as a packet”
- Location and group management
- Complete tests with other LIFX devices & other brands
- A better security