Huenicorn

Journey

Preamble

The intention behind this page is to communicate in a more open and informal way about Huenicorn.

Release notes and ReadMe are technically informative but they don't give much clue about how this project matters to me and how this brought some fresh air and confidence in my tech life.

So this page will bring you through a short introduction about my background, then it will expose the key steps that shaped Huenicorn as it is with the thoughts and challenges that followed.

Some personal background

My passion with programming started long ago with some small GameMaker projects in early 2000. For sure, this didn't make me a "real programmer" but this taught me the very basics of algorithmic and awoke my curiosity.

Later, things became more serious when I ran into web development, learned C++ then fell in love with GNU/Linux, also had fun with OpenGL before finally going to engineering school and forcing myself to get a bachelor degree. Academically, this was enough for me. I've never been good at school anyway.

Since my degree, I work as software engineer but I can't help but feel like I'm a better hobbyist than professional in the sense that I learn and progress much more through my personal projects than from the duty of work experience.

Currently, I work part-time in order to have more free time to dedicate to projects that really inspire me. Huenicorn is one of them.

Hey, I want bias lighting too !

Huenicorn started in late 2022 after a friend told me about his gaming computer setup. He explained that he got his bias lighting with Philips Hue Play™ lamps. Even though I never even owned "smart bulbs" before, I was immediately interested in getting the same effect. However... something was to be expected : Philips doesn't provide official driver for GNU/Linux systems regarding bias lighting.

Nevertheless, I ordered a Hue Bridge and a few Hue lightbulbs in order to test some things first. In the worst case senario, they would then still be funny lightbulbs for my home I could command from my phone.

Got some gear... Now what ?..

After some research, I found a few programs for my system able to provide bias lighting. Alas, even though some worked decently, they didn't feel really convenient to me.

Maybe, if I am that picky, I should use my programming skills to make something by myself ?

I found about the official Philips Hue™ "Get Started" guide and very quickly I could turn the lights on and off and even set some colors from my web browser through HTTP requests. At this point, this was enough to convince me that I could really make something by myself !

In a short time I started to write some C++ code to get an automated screen capture through X.Org, to compute the capture's dominant color, then to send the color to the bridge through hardcoded HTTP requests. I was really excited by how quickly I had a working color feedback.

It can be worth sharing but first...

My stuff was "working" and I really desired to share it but at that time, the code was a mess ! Everything was hardcoded and there was no easy way to manage the lights. Furthermore, the project still did not have a proper name either and I was deperately looking for a pun with "Hue" but nothing was coming...

So in my effort to make this project usable by others, I started by trying my best at designing a smooth web UI. At first, the interface was black with a white aura on boxes. As I was not really convinced, I added an easter egg to enabled some rainbow shift upon adding the url parameter "unleashTheUnicorn".

After some time, I was really pleased with this easter-egged rainbow shift. Maybe people wanting bias lighting wouldn't mind having some rainbowish interface by default. So the rainbow became the norm !..

... And suddenly, a revelation came to me during the process of setting the default style... I realised that the project name was found unconsiously weeks ago... It was right before me my eyes for weeks... Unleash the Unicorn... Hue... Huenicorn !

It is time !

Everything was looking good enough to me for a first public introduction. I pushed the version 0.0.0 (now Legacy) on my GitLab repository and made an annoucement on Reddit... Then I was baffled by the unexpectedly high visibility it gave to the project. This spooked me at first. Fortunately, the comments were very enthusiastic. That really made me want to go further because, actually, given the spotlight Huenicorn had, I felt that the version I presented here first was far from perfect. Indeed, it was still running with HTTP requests with all their related slowness issues...

Quick ! How to make it not laggy ?!

Indeed, using HTTP, the Hue Bridge could only accept 10 requests per seconds. And so far, as I finally acquired some "Hue Play" lamps, Huenicorn was now soliciting the Bridge 3 x 60 = 180 times per seconds... which was about 18 times over the recommendations. Sorry Bridgy... It's for science ! The poor thing was already starting to lag when exceeded by a factor of 2.

A solution had to be found because this current workflow was absolutely not scalable and terribly slow and I could not afford to ship fire extinguishers to users. So I found out that the "Hue API V2" was the actual way to overcome the Hue Bridge limitations. So I dived into its documentation.

The light management had to be reworked. Huenicorn no longer had to address lightbulbs separately but to subscribe to an "Entertainment configuration" and streaming color data through UDP. It took some time to get the code right in order to get a SSL "Handshake" to work. Networking is not my favorite thing but it was really interresting to learn how to set up a stream through MbedTLS.

Once the networking witchcraft settled, Huenicorn was now able to address up to 32 light channels per frame. Colors could be streamed in real time and the bridge was holding it perfectly !

Oh wow, contributors !

I was traveling at the time I noticed – with some delay, sorry – the first ever merge requests on the repository. Realizing that people invested their time to get through the code and make some relevant changes on Huenicorn made my day. I finally released something that people use and spontaneously enhance !

"What about Wayland ?"

Some time passed since the smooth streaming update. Huenicorn has been running very well but there still was a big limitation I was aware of : Huenicorn was only supporting X.Org.

At the current time, GNU/Linux systems are transitionning between two display protocols. On one hand, there is the good old X.Org that is old school and permissive. On the other hand, there is Wayland that holds a more modern architecture including stricter interprocess rules.

The question about wayland support came very early. Most of the time, I heard/read that there is no "standard way" to take screen captures under Wayland and that this task was going to be difficult. For almost a year, I postponed this from fear of losing my mind trying. But time is ticking and more and more casual GNU/Linux distros are moving to Wayland by default. If nothing was done soon, Huenicorn would be doomed to retire along with good old X.Org...

Time to overcome the fear !

Definitely, Huenicorn deserves a future. So I started reading codes of projects involving screen captures. OBS-Studio source code has been my candle in the darkness. I unwrapped hundreds of lines of its code and gave my best to decipher anything useful I could find. I understood that there were only two main steps to achieve to reach the holy grail:

  • Opening a session through XDG-Screencast-portal
  • Feeding it to Pipewire to get its content

After mixing various code samples from Pipewire tutorials and other projects for weeks, I could finally witness something... Frames !

Well, at least, Pipewire told me it got some buffers with a size of 19814400 bytes so, let's check if this makes sense : 1981440 / (3440 * 1440) = 4. The frame was definitely matching the resolution of my screen ! (4 was because the frame was RGBA.)

Quick ! Gimme the pixels as RGB ! Save them as "out.PLEASEPLEASEPLEASE.png" ! Hey ! That really IS a capture of my screen !

This was one of the the greatest reliefs I had on this project. All that was left to do was to clean the code and fit it into a Grabber class and there it was !

I believe in Free Software

I have been exclusively running on GNU/Linux systems since 2011. For all this time, I benefit from this huge Free Sofware community that provides most of my software ecosytem. A significant part of the things I have learned in the IT field came to me thanks to this core principle of sharing knowledge and building things together without greed nor desire to control others.

Lots of free softwares have become very good alternatives and even industry standards in many fields.

For the artistic ones, their spontaneous and mainstream adoption is an encouraging proof that Free Software went a long way ahead towards end-users and that we no longer have to chose between freedom or convenience.

Making my code follow this philosophy was the least I could do in return.

Conclusion

Huenicorn is a very satisfying project. This is the first time I dare to publish something, and so far, this is a very positive experience. The things I am learning through this journey are valuable. I am genuinely grateful for your requests, feedbacks and contributions. They bring value to this project and reinforce my dedication.

I have currently no idea how many people use Huenicorn but being aware that you follow this project made me acknowledge my responsibility.

The promise I can make is, as I am probably the main user of Huenicorn, I will take good care and do my best to keep it up and running.

Thank you for having taken the time to read !

May Huenicorn enlight your multimedia activities !

OpenJowel