Hyelicht is an IoT/embedded project for home decoration/automation. Its software allows you to do colorful painting and animations on a LED-backlit shelf, using an embedded touchscreen and a companion app for phones and PCs. It also offers integration with a smart lights system.
Hyelicht's reference hardware is a 5x5 IKEA Kallax shelf with multiple rows of LED backlighting and a side-mounted 7″ touchscreen integrated into an aesthetically-pleasing picture frame. A single-board computer running Linux, a helper MCU and two 12A 5V bench power supplies are hidden inside the shelf.
A photo of the assembled shelf can be found here.
- Responsive Touch GUI with support for landscape and portrait orientations
- Turn shelf on/off, adjust brightness, painting tools, trigger animations
- Runs synchronized on embedded touchscreen and multiple Android/PC devices
- Runs in-process or standalone
- SK9822/APA102 LED paint engine supporting gamma correction and HSV-based brightness derivation
- Animation framework
- Fireplace animation 🔥
- Embedded display backlight control with MCU-generared PWM signal
- Smooth display fade-in on user interaction, fade-out on idle timeout
- HTTP REST API
- CLI frontend utility
hyelichtctl
(HTTP-based), works locally and over the network - Home Assistant integration
- systemd integration (service unit)
- Doxygen-based documentation
- REUSE- and SPDX-compliant free software written in C++17 and QML
A photo of the assembled shelf can be found here.
Most of Hyelicht is available under GNU GPL v2. All licenses used in the project:
- GNU GPL v2.0, v3.0 or any later version approved by KDE e.V. (Most source code)
- LGPL-3.0-or-later (Most icons)
- CC-BY-4.0 (Most other graphical assets, metadata and documentation)
- BSD 3-Clause "New" or "Revised" License
- Creative Commons Zero v1.0 Universal
The codebase is REUSE- and SPDX-compliant. See files in LICENSES/
and .reuse/dep5
.
- Documentation
- Installation and using
- HTTP REST API
- hyelichtctl CLI utility
The full Hyelicht system contains the following elements:
(See below for additional detail on wiring.)
Hyelicht has a main application codebase with multiple build+runtime modes for onboard (embedded with or without in-process Touch GUI) and standalone Touch GUI (client) use. A monolithic-by-default single-application architecture was chosen to minimize resource needs and loading times in onboard mode. Internally, the application heavily optimizes for each mode. For details on how to choose the mode, see the sections on build options and command line options.
In onboard mode, the application controls the LED strip and the display backlight (with the help of additional software on a companion MCU) and offers servers for instances running in Touch GUI mode as well as HTTP clients. In standalone Touch GUI mode, these features are disabled and the application acts as a pure client only.
Additionally, the onboard application can also be run in headless mode. This disables the in-process Touch GUI. An additional instance in Touch GUI mode can then be run as a pure client on the same device, if process separation is desired.
Included clients to the HTTP REST API include a command line frontend utility hyelichtctl
and a Home Assistant integration.
Hyelicht's source code has full Doxygen-based documentation. You can browse a generated snapshot of the latest documentation here.
If you want to generate the documentation locally yourself, please check the build instructions.
Hyelicht has a largely platform-agnostic codebase that should build and run on any platform providing its build dependencies. However, its custom LED paint engine makes use of a Linux-specific API for SPI communication.
Hyelicht is being tested on the following hardware and software:
- Onboard mode:
- Raspberry Pi 4B running Raspberry OS
- Waveshare 7″ 1024x600 capacitive touchscreen, version H
- Standalone Touch GUI mode:
- Desktop PC: Fedora Linux
- Android phone: Android+Qt+KDE SDK via the KDE Android Docker image and several Android 11/12 phones
- LED strips: 416x SK9822, 60 LEDs/m
- Helper MCU: Android Nano 3.0 (AVR ATmega328)
See section Architecture for an explanation of the modes.
The reference hardware for the project uses SK9822 LEDs from 60 LED/m strip reels. However, the custom LED paint engine should also be compatible with APA102 LEDs. The SK9822 is a later clone of APA102 with minimal differences in the accepted input.
In onboard mode, the Hyelicht application uses serial communication to a helper MCU that drives the embedded display backlight with a PWM signal. The helper MCU is expected to read 8-bit integer values between 0
and 255
on serial and convert them to the corresponding signal. In principle, any MCU programmed to conform to this expectation will work.
The reference hardware used in the project is an Android Nano 3.0 (AVR ATmega328). See src/arduino_pwm_generator.cpp
for the reference program.
- C++17-supporting C++ compiler
- CMake v3.16+
- Qt v5.15+ modules QtCore, QtNetwork, QtQML, QtQuick, QtRemoteObjects
- KDE Frameworks 5 v5.78+ modules Extra CMake Modules/ECM, KCoreAddons, KConfig, KI18n from
- Linux headers (for SPI)
- For onboard builds:
- Qt v5.15+ module QtSerialPort
- QHttpEngine v1.0.1+
- For Android builds:
- Qt v5.15+ module QtAndroidExtras
- Android v30+ SDK+NDK (see below)
- For documentation builds:
- Doxygen v1.8.8+
- Doxyqml
A convenient way to access a complete Android+Qt+KDE SDK is via the KDE Android Docker image.
- Raspberry OS: SPI enabled
- For clang-tidy developer build configuration: clang-tidy
- arduino-cli or Arduino IDE
Hyelicht has a CMake-based build system. Here are some general build commands:
(Hyelicht codebase is in directory `hyelicht`.)
$ cd hyelicht/
$ mkdir build && cd build/
$ cmake ../build -DCMAKE_INSTALL_PREFIX=<install path>
$ make
$ sudo make install
When running the cmake
command, you may want to pass additional build options, like so:
$ cmake ../build -DSOME_OPTION=value
See below for available build options and their default values.
Building for Android is easy using the KDE Android Docker image.
See the support/kde_android_docker_build.sh
build script and its embedded comments for specific instructions.
To generate source code documentation using Doxygen during a build, enable the BUILD_DOCS
build option.
See the build instructions for how to set these options when building Hyelicht.
Option | Default | Description |
---|---|---|
BUILD_ONBOARD | TRUE unless Android build | When enabled, additional features and command line options become available that only make sense when Hyelicht is running in onboard mode on the hardware embedded into the shelf. For example, code driving the LEDs and the embedded display backlight, and servers for the Touch GUI and HTTP clients. This alters the list of build dependencies. |
BUILD_CLI | TRUE unless Android build | Builds the HTTP-based hyelichtctl command line utility. |
Option | Default | Description |
---|---|---|
BUILD_DOCS | FALSE | Generates project documentation using Doxygen. This alters the list of build dependencies. The generated documentation will appear inside the docs/html/ sub-directory of the build directory. |
CLANG_TIDY | FALSE | Reformats the source code using clang-tidy. |
COMPILE_QML | TRUE | Pre-compiles QML source files for faster loading speeds. |
DEBUG_QML | FALSE | Enables the QML debug server. |
In the onboard build configuration, Hyelicht installs a systemd service unit. It is recommended to use it as a user unit, like so:
$ systemctl --user enable hyelicht
If you just installed Hyelicht, you may need to run systemctl --user daemon-reload
first. For user units to start at boot, you may need to enable lingering (see enable-linger
) for the user.
The service unit starts the application in onboard mode and sets several environment variables specific to the project's embedded reference hardware. It instructs Qt to select the EGLFS backend plugin, which handles GPU interaction for the Touch GUI. Other variables set the screen resolution for the embedded touchscreen. See the Qt for Embedded Linux page for additional information.
Plugin code for simple integration with Home Assistant is provided at support/homeassistant/hyelicht
.
Copy the hyelicht
folder into <Your Home Assistant config dir>/custom_components
(create the folder custom_components
if necessary), then add the integration from your Home Assistant settings menu. You will be prompted for the host address and port of the Hyelicht shelf.
The integration plugin acts as a client to the HTTP REST API.
The LEDs are connected to the Raspberry Pi 4B and the bench PSUs (part of the reference hardware used by the project) as follows:
In the actual shelf, there are two 12A 5V bench PSUs to power 416 LEDs (50 mA each at full brightness). Both PSUs are connected to both ends (5V and GND) of two LED strips each, with each LED strip having 104 LEDs. Connecting to both ends potentially improves signal integrity (GND) and avoids a one-sided brownout if (5V), should your PSUs be too weak (instead, the brownout would occur in the middle of the strips). All grounds are connected, including the Raspberry Pi's, to ground the SPI connection.
The Raspberry Pi, and the helper MCU and the embedded touchscreen connected to it, is seperately powered via the official Raspberry Pi USB-C power supply. The inputs and outputs of all three PSUs are connected on a single wall power plug.
See also the system diagram.
The main application executable is named hyelicht
. It can be run manually:
$ hyelicht
Or via the included systemd service unit, which conveniently sets command line options and environment variables suitable for an embedded deployment. Check the linked section for detailed information.
If you want to try out Hyelicht's embedded GUI on your PC without having LEDs handy, run a default build like this:
$ hyelicht --onboard --simulate-shelf --simulate-display
The hyelichtctl
command line utility is described below.
hyelicht
supports standard command options options such as -h, --help.
Various command line options will override an equivalent setting that can be changed via the config file.
Command line options unique to hyelicht
:
Option | Default | Description |
---|---|---|
-r, --remotingApiServerAddress | from Settings | Overrides the address Touch GUI client instances contact the remoting API server on. If unset, the listen address is taken from the settings (see the section Config file). |
Option | Default | Description |
---|---|---|
-o, --onboard | UNSET | Runs the application in onboard mode. This is used by the systemd service unit. |
--headless | UNSET | Disables the in-process Touch GUI. Useful if running the GUI out-of-process as a standalone client instance is desired. |
--simulateDisplay | UNSET | Disables serial communication to the helper MCU and simulates display backlight status in the Touch GUI. |
--simulateShelf | UNSET | Disables SPI communication with the LED strip. The Touch GUI and all APIs can be used regardless. |
-s, --httpListenAddress | from Settings | Overrides the listen address for the HTTP REST API server. If unset, the listen address is taken from the settings (see the section Config file). |
-p, --httpListenPort | from Settings | Overrides the port the HTTP REST API server listens on. If unset, the listen address is taken from the settings (see the section Config file). |
--disableHttpApi | from Settings | If set, disables the HTTP REST API server. If unset, whether to enable this API server is taken from the settings (see the section Config file). |
-l, --remotingApiListenAddress | from Settings | Overrides the listen address for the remoting API server used by Touch GUI client instances. If unset, the listen address is taken from the settings (see the section Config file). |
--disableRemotingApi | from Settings | If set, disables the remoting API server. If unset, whether to enable this API server is taken from the settings (see the section Config file). |
Hyelicht supports a config file in INI-style format. It should be located at $XDG_CONFIG_HOME/hyelichtrc
or in an equivalent system or user location following the XDG Base Directory specification.
See the XML source file src/settings/hyelicht.kcfg
for the INI group and key names and the description and default value of each setting. Those attempting to build their own shelf (something the authors hope you may do!) will are likely to take special interest in the various settings related to shelf size and server addresses.
Hyelicht's applications can output error and debug messages on stdout
and stderr
using Qt's categorized logging framework.
When you run hyelicht
or hyelichtctl
manually, you should enable its logging categories to see this output:
$ export QT_LOGGING_RULES=com.hyerimandeike.*=true
$ hyelicht
If the application is run via the included systemd service unit, the categories are enabled by default and messages can be looked up in the journal:
$ journalctl --user -u hyelicht.service
The complete list of logging categories:
Name | Description |
---|---|
com.hyerimandeike.hyelicht | General messages |
com.hyerimandeike.hyelicht.Animations | Animation framework |
com.hyerimandeike.hyelicht.DisplayController | Serial communication with helper MCU for display backlight control |
com.hyerimandeike.hyelicht.HttpServer | HTTP REST API server |
com.hyerimandeike.hyelichtctl | hyelichtctl command line utility |
com.hyerimandeike.hyelicht.LedStrip | SPI communication with LED strip and LED paint engine |
com.hyerimandeike.hyelicht.Remoting | Communication between onboard and standalone Touch GUI clients |
In onboard mode, the main application offers a HTTP REST API (unless disabled via the Config file or command line option.) with the following available resources:
Resource | Supported methods |
---|---|
v1/shelf | GET |
v1/shelf/enabled | GET, PUT |
v1/shelf/brightness | GET, PUT |
v1/shelf/averageColor | GET, PUT |
v1/shelf/animating | GET, PUT |
v1/squares | GET, PUT |
v1/square/:index/averageColor | GET, PUT |
Data is returned and accepted in JSON format.
See the system diagram to understand the numbering of squares for square indices.
The HTTP REST API is used by the included hyelichtctl
command line frontend and the Home Assistant integration.
The hyelichtctl
command line utility can be used to check on and control various aspects of the shelf. It is a client to the HTTP REST API of the onboard application and can therefore run both locally and remotely, depending on the onboard configuration.
hyelichtctl
is run like this:
$ hyelichtctl [options] command [args...]
Supported commands are:
Command | Parameters | Description |
---|---|---|
status | none | Returns shelf status, including enabled, brightness, average color, etc. |
enabled | [bool] | Reads or sets enabled status of the shelf. |
enable | none | Enables the shelf. |
disable | none | Disables the shelf. |
brightness | [0.0 - 1.0] | Reads or sets the shelf brightness. |
color | [square index] [color] | Reads or sets the color of the shelf or a square. |
animating | [bool] | Starts or stops the animation. |
See the system diagram to understand the numbering of squares for square index.
A color can be a CSS color name or a RGB HEX color code.
Supported command line options are:
Option | Default | Description |
---|---|---|
-s, --server | 127.0.0.1 | The server address to contact the onboard application at. |
-p, --port | 8082 | The port to contact the onboard application on. |
-j, --json | UNSET | If set, the output is in JSON format instead of more easily-read INI-style. |
Additionally, standard command line options such as -h, --help are supported as well.