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
- 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
- Philips Hue smart lights integration: HTTP-based plugin for the diyHue open source bridge emulator
- 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
Table of Contents
- Installation and using
- Supported platforms
- Build instructions
- Build options
- Config file
- 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.
If you want to generate the documentation locally yourself, please check the build instructions.
Installation and using
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.
Helper MCU (PWM signal generator)
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
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.
General build dependencies
- 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)
Optional build dependencies
- 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+
A convenient way to access a complete Android+Qt+KDE SDK is via the KDE Android Docker image.
Optional runtime dependencies
- Raspberry OS: SPI enabled
- For clang-tidy developer build configuration: clang-tidy
Build dependencies for included helper MCU program
- 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=
$ 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.
support/kde_android_docker_build.sh build script and its embedded comments for specific instructions.
See the build instructions for how to set these options when building Hyelicht.
|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
|BUILD_DOCS||FALSE||Generates project documentation using Doxygen. This alters the list of build dependencies. The generated documentation will appear inside the
|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.|
systemd service unit
$ 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.
diyHue integration plugin
Plugin code for simple integration with diyHue is provided at
However, diyHue does not support external plugin installation and must be patched to use the plugin. The shelf must also be manually added to the diyHue configuration. Both are left as an exercise for the reader.
The 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:
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.
hyelichtctl command line utility is described below.
Command line options
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
|-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).|
Additional command line options for onboard build configuration
|-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
stderr using Qt's categorized logging framework.
When you run
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:
|com.hyerimandeike.hyelicht.DisplayController||Serial communication with helper MCU for display backlight control|
|com.hyerimandeike.hyelicht.HttpServer||HTTP REST API server|
|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|
HTTP REST API
Data is returned and accepted in JSON format.
See the system diagram to understand the numbering of squares for square indices.
hyelichtctl CLI utility
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:
|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:
|-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.