<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Felix Döring's blog</title>
  <subtitle>New posts on software development, DevOps and hardware tinkering.</subtitle>
  <link href="https://felixdoering.com/en/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="https://felixdoering.com/en/"/>
  <id>https://felixdoering.com/en/</id>
  <updated>2026-07-26T21:47:12+02:00</updated>
  <author>
    <name>Felix Döring</name>
    <email>mail@felixdoering.com</email>
  </author>
  <entry>
    <title>How smart a radiator thermostat can be</title>
    <link href="https://felixdoering.com/en/blog/smart-radiator-thermostat/"/>
    <id>https://felixdoering.com/en/blog/smart-radiator-thermostat/</id>
    <published>2023-01-21T16:45:00+01:00</published>
    <updated>2023-01-22T13:00:00+01:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>Apart from the fact that I wanted to make my home smarter bit by bit for some time now, the current rise in energy costs gave me one more reason to...</summary>
    <content type="html">&lt;h2 id=&quot;the-reason&quot;&gt;The reason&lt;/h2&gt;

&lt;p&gt;Apart from the fact that I wanted to make my home smarter bit by bit for some time now, the current rise in energy costs gave me one more reason to replace the thermostats of the radiators in my flat with smart versions. The ability to control the temperature of my home by means of set schedules, via an app or depending on my presence not only increases comfort, but also reduces heating costs.&lt;br /&gt;
Nevertheless, which thermostats should I choose? And why are there such incredibly wide price ranges?&lt;/p&gt;

&lt;h2 id=&quot;the-purchase-decision&quot;&gt;The purchase decision&lt;/h2&gt;

&lt;p&gt;At the beginning of December 2022, I made up my mind to get new and smart heating thermostats. I drew up a list of minimum requirements to reduce the large number of products somewhat. My main concerns were that they were compatible with Apple HomeKit and, above all, reliable. There are enough products whose reviews report constant communication loss despite a short distance to the bridge.&lt;br /&gt;
In the end, the decision was made in favour of a system from tado°, as the devices are relatively small and unobtrusive. One slight drawback, however, is that some of the “premium” features of the app require a monthly subscription. Among other things, the absence detection and automatic switching of the radiators are just some of those functions. If you don’t want to pay €3 a month for this, you will only be informed via push notifications if the system has detected an open window or that no person is present. As with most smart home devices, presence detection is realised via &lt;a href=&quot;https://en.wikipedia.org/wiki/Geo-fence&quot;&gt;geofencing&lt;/a&gt;. Registered smart phones send their GPS coordinates and get checked whether they are within a virtually ‘fenced’ area.&lt;/p&gt;

&lt;h2 id=&quot;the-not-so-smart-thermostat&quot;&gt;The not so smart thermostat&lt;/h2&gt;

&lt;p&gt;The truth is: I would have run into pretty much the same problems if I would have chosen a different thermostat. Sooner or later, you always come up against the limits of the devices. In my case, the temperature that the thermostats measure near the radiators is often much higher than the actual temperature in the middle of the room, so they don’t continue heating even though the target temperature hasn’t been reached yet. Geofencing via tado itself also consumes an incredible amount of battery charge. On top of that, this kind of notification function is very likely designed in such a way that at some point you no longer want to use it and simply would pay. A solution was needed, and one that does not incur any ongoing costs.&lt;/p&gt;

&lt;h2 id=&quot;an-assistant-for-home-and-heating&quot;&gt;An assistant for home and heating&lt;/h2&gt;

&lt;p&gt;Software developers are generally too proud to pay money for functions that they could build themselves. I felt the same way, because I was tired of manually switching the heating to “away” and back to “home”. In that case I could have kept the previous thermostats. Fortunately, there is open source software that helps you gain some control and unification over all the manufacturers with their own cloud, bridge and proprietary protocols. My choice fell on &lt;a href=&quot;https://www.home-assistant.io&quot;&gt;Home Assistant&lt;/a&gt;.&lt;br /&gt;
Once integrated into Home Assistant, the tado devices provide all the data that they also make available to the app. This includes the open window detection, which would normally only trigger a notification. Only the location data or the information whether registered devices are in the vicinity are not provided. Fortunately, Home Assistant can do this on its own, without the need for a cloud. Everything is evaluated locally.&lt;br /&gt;
So I set up an automation that tells tado to switch the heating to “away” mode as soon as there is no device nearby and revoked the tado app’s permission to use location data. Suddenly, my battery lasts much longer again. It also reacts to open windows registered by tado and sets the heating to a lower temperature for this time, just like in the premium functions.&lt;/p&gt;

&lt;h2 id=&quot;it-is-still-too-cold&quot;&gt;It is still too cold&lt;/h2&gt;

&lt;p&gt;It is possible to set an offset to compensate for the temperature difference between the room and the radiator. Nevertheless, in my case this has always been very variable between 1 and 3 Kelvin. So often it was still relatively cold in the room, but the thermostat thought it was already just below 26 °C. Unfortunately, you cannot tell tado the actual room temperature directly. One option is to purchase the additional thermometer from tado itself, which costs a little more than the actual radiator thermostat. Alternatively, you can go back to Home Assistant and integrate much cheaper temperature sensors, with the help of which the offset is ultimately updated dynamically via an automation. At this point, the disadvantage of evaluating all data in the cloud without any external context becomes apparent once again. Because of manually adjusting the room temperature using the offset, tado believes it has detected an open window, which only leads to false positive results. So I deactivated this detection and use door and window opening sensors, which not only react reliably, but also immediately, and not only after a drop in temperature.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Now everything heats according to my wishes, even if I had to buy some additional sensors. In the end, the additional investment is one-off and also cheaper than being completely locked into the tado universe.&lt;br /&gt;
If you ask me whether I regret my decision to choose this manufacturer, my answer is: No, not really. As mentioned before, every product has its own peculiarities and with other manufacturers my hands would have been tied even more in some cases. Nevertheless, I am happy when new standards like &lt;a href=&quot;https://en.wikipedia.org/wiki/Matter_(standard)&quot;&gt;Matter&lt;/a&gt; are introduced, which allow devices to be operated exclusively locally and also independent of manufacturers. Theoretically, there are already some wireless standards like Zigbee or Z-Wave for this, but do manufacturers still have the possibility to restrict functionalities enormously here - Yes, I’m talking about Philips Hue, whose hub does speak Zigbee, but only in the Light Link protocol. If a company pays to be included in the “Friends of Hue” programme, strangely enough, their temperature sensors can also be integrated.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>The never-ending weather station project</title>
    <link href="https://felixdoering.com/en/blog/never-ending-weather-station/"/>
    <id>https://felixdoering.com/en/blog/never-ending-weather-station/</id>
    <published>2022-03-16T15:30:00+01:00</published>
    <updated>2022-03-16T15:30:00+01:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>Over the course of the now almost seven years, I have returned to my weather station project from time to time. No matter whether it was a refresh...</summary>
    <content type="html">&lt;h2 id=&quot;the-beginnings&quot;&gt;The beginnings&lt;/h2&gt;

&lt;p&gt;I first wrote about a weather station in a blog article in July 2015. At the time, it consisted of a Raspberry Pi, a DTH22 and a LCD display. Everything was thrown together in a very rudimentary way with a script that crashed regularly. Also, the term weather station may have been a bit exaggerated. A sensor that can measure temperature and humidity and a display that only shows these live values is still a thermometer.&lt;br /&gt;
But that’s how my long journey of “weather stations” began back then in my dormitory room.&lt;/p&gt;

&lt;h2 id=&quot;what-has-happened-so-far&quot;&gt;What has happened so far&lt;/h2&gt;

&lt;p&gt;Over the course of the now almost seven years, I have returned to this project from time to time. Be it a refresh of the original project or a new attempt in another programming language. A completely new turn of events occurred on my birthday three years ago. I received a box that contained a BMP280 (for air pressure), an MQ135 (gas sensor) and the DHT22 I already knew. Also, the whole project should no longer run on a Raspberry Pi, but on the ESP8266, a microcontroller similar to the Arduino with integrated WIFI. Actually a nice new playground for a hobbyist like me. I put everything together and wrote a bit of software for it. That was also the moment when I discovered &lt;a href=&quot;https://platformio.org&quot; title=&quot;External Link: PlatformIO project website&quot;&gt;PlatformIO&lt;/a&gt; for myself.&lt;/p&gt;

&lt;p&gt;The components assembled on a breadboard were relatively unstable and I had also watched a tutorial on PCB prototyping shortly before. So the logical next step for me was to create my own PCB, which provided a socket for the ESP and connections for the three sensors. The end result, in my opinion, finally deserved the title “weather station”. But then the big plans came: What if I distributed several of these stations in the apartment? And what if they all send the current data to my server? For that, I would need an API and, ideally, a small configuration option on the devices themselves. And when all this is finished at some point, I can tackle a third project, a display that shows me all gathered values in a nice format.&lt;/p&gt;

&lt;p&gt;After experimenting with the hardware for a while, I decided to upgrade. The ESP8266 had to give way to an ESP32, which had more memory and processing power. Unfortunately, I lost my old project files for the PCB, so I made it again with the updated components. No difference really, just the better microprocessor.&lt;/p&gt;

&lt;h2 id=&quot;all-good-things-come-in-threes&quot;&gt;All good things come in threes&lt;/h2&gt;

&lt;p&gt;Again, some time had passed and in the meantime I had done some work on SMD soldering and further expanded my knowledge of circuit board design through tutorials. For SMD soldering, the components are not pushed through the PCB as it is usual in the hobby sector, but are designed in a way that they are only attached to the surface.&lt;br /&gt;
I was wondering what sensors are really useful for monitoring and recording temperature, humidity and air pressure. All three values can be measured with a Bosch BME280. Theoretically, this is also available prefabricated on a circuit board, which could simply be connected to the ESP via simple plug connection. The point is, I like to complicate things and maybe I’m using this project as a bit of an excuse to try my hand at new things. So I looked around for schematics of ESP32 development boards and found what I was looking for at Adafruit. At this point, a big thank you to the developers at Adafruit, who make almost their entire products, including the schematic drawings and PCB files, available as open source! This really helped me a lot to get inspiration for my own design. So I put together a PCB that contains an ESP32 as well as a BME280 and can be operated either via USB-C, battery or DC plug.&lt;br /&gt;
I haven’t found the time yet to actually populate the PCBs with the components, but hopefully that will happen very soon. I am curious to see in which direction this project will develop.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Things about Search Engine Optimization</title>
    <link href="https://felixdoering.com/en/blog/things-about-seo/"/>
    <id>https://felixdoering.com/en/blog/things-about-seo/</id>
    <published>2022-02-27T18:45:00+01:00</published>
    <updated>2022-02-27T18:45:00+01:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>SEO, short for &quot;Search Engine Optimisation&quot;, is at the same time a great but also a difficult thing. It is the process...</summary>
    <content type="html">&lt;h2 id=&quot;what-is-seo&quot;&gt;What is SEO?&lt;/h2&gt;

&lt;p&gt;SEO, short for “Search Engine Optimisation”, is at the same time a great but also a difficult thing.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;[It] is the process of improving the quality and quantity of website traffic to a website or a web page from search engines.
&lt;cite&gt;– Source: &lt;a href=&quot;https://en.wikipedia.org/wiki/Search_engine_optimization&quot;&gt;Wikipedia&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Above all, SEO refers to unpaid traffic of websites, i.e. appearing as high as possible in search results without (regularly) spending money on it.&lt;br /&gt;
Besides the content, which I will discuss later, the general performance of the page is very important. How and when is the CSS loaded, do elements block the page layout, how quickly does the server respond. All these things and more need to be considered if you want to improve your SEO.&lt;br /&gt;
Googles &lt;a href=&quot;http://pagespeed.web.dev/&quot;&gt;PageSpeed Insights&lt;/a&gt; are a good way to get an overview of how they rate the performance of your pages. If it was only about that, I would have been done with SEO because of rating of 99 on desktop and 100 on mobile devices.&lt;/p&gt;

&lt;h2 id=&quot;content-matters&quot;&gt;Content matters&lt;/h2&gt;

&lt;p&gt;Content is likewise a very important point for me to optimise. The more content and sub pages a website has, the more can be indexed by search engines. And the larger the index, the better the ranking. If relatively similar content is present on several pages, this again hurts the ranking. Google says the following about duplicate content:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Google tries hard to index and show pages with distinct information.
&lt;cite&gt;– Source: &lt;a href=&quot;https://developers.google.com/search/docs/advanced/guidelines/duplicate-content?hl=en&amp;amp;visit_id=637810316108825221-1174314324&amp;amp;rd=1&quot;&gt;Google&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, in the broadest sense, this blog post with my experience of SEO optimisation leads to more content on my site and therefore a better chance of being displayed higher up in the search results.&lt;/p&gt;

&lt;h2 id=&quot;not-only-text-is-content&quot;&gt;Not only text is content&lt;/h2&gt;

&lt;p&gt;Search engines are not only interested in the text of a page, but also in meta information. Strictly speaking, this is also text, but it is not displayed directly on the page itself. For example, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;title&amp;gt;&lt;/code&gt; is also used in the browser as a caption for the tab, but mainly by search engines together with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;meta name=&quot;description&quot;&amp;gt;&lt;/code&gt; and for some also the favicon to be displayed in the search results. Keywords, while still recommended, are no longer considered in most indexes due to misuse. Instead, the most important keywords of the text should be found in the title and the URL.&lt;br /&gt;
For sharing the website in social networks, Facebook and Twitter have also added their own meta information (&lt;a href=&quot;https://ogp.me&quot;&gt;Open Graph protocol&lt;/a&gt; and &lt;a href=&quot;https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup&quot;&gt;Twitter cards&lt;/a&gt;). These enrich the preview with additional information when sharing on the respective platforms. SEO rewards these efforts of the website operator. The same goes for embedded functions that allow sharing directly from the page. On my website, however, I wanted to renounce all sharing features.&lt;/p&gt;

&lt;h2 id=&quot;the-link-to-a-page&quot;&gt;The link to a page&lt;/h2&gt;

&lt;p&gt;The URL of a post or page should contain keywords that are also found in the text and title. URLs should neither contain any filler words nor exceed a certain length. This way, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/blog/things-about-seo&lt;/code&gt; gets a better SEO rating than a full sentence, for example (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/blog/things-i-learned-about-seo&lt;/code&gt;), even if it would make it easier for the end user to understand that this is a experience report and not a tutorial. The trick is to make URLs “speaking” enough without overloading them.&lt;/p&gt;

&lt;p&gt;Jekyll generates, if configured, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index.html&lt;/code&gt; for each Markdown file which is stored in a folder structure representing the URL. If you now link to this page, it works with and without an attached &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/index.html&lt;/code&gt;, because my Nginx always searches for this file in a directory. For Google and other search engines, however, these are two separate locations. So that the page is not seen as duplicate content, it is important to add a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rel=&quot;canonical&quot;&lt;/code&gt; to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag when linking to it. This indikates that this is only a single location.&lt;/p&gt;

&lt;h2 id=&quot;it-has-to-look-good-on-mobile&quot;&gt;It has to look good on mobile&lt;/h2&gt;

&lt;p&gt;Who does not have them, the friends to whom you send a link and not two minutes later you get a reply like: “It’s really not suitable for mobile”. Annoying when you just want to show them something, but actually correct. Nowadays, websites are viewed much more frequently on mobile devices such as phones and tablets. Therefore, Google is also very interested in the so-called mobile responsiveness when evaluating a page.&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;By design, Jekyll does not really contribute much to SEO. There is a plugin that inserts the most important meta information, but everything else is up to the user. However, I have found for myself that all these optimisations, and a few more not listed here, are slow to have an effect. A great SEO result does not automatically equate to an immediate good rank in the search results. If, on the other hand, the SEO deteriorates, for example due to the omission of a page that is still present in the search engines’ index, however, an immediate downgrading follows.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Hello new old world</title>
    <link href="https://felixdoering.com/en/blog/hello-world-again/"/>
    <id>https://felixdoering.com/en/blog/hello-world-again/</id>
    <published>2022-02-01T13:00:00+01:00</published>
    <updated>2022-02-01T13:00:00+01:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>Why do people create their own websites? Either to promote themselves or to tell their stories in blog form. But...</summary>
    <content type="html">&lt;h2 id=&quot;my-reflections-on-the-old-website&quot;&gt;My reflections on the old website&lt;/h2&gt;

&lt;p&gt;Why do people create their own websites? Either to promote themselves or to tell their stories in blog form.&lt;br /&gt;
But what would I like to achieve with my website? The previous iteration was a pure blog and a collection of projects I was working on at some point. Also the preceding blog entry was over four years ago and my style of writing has changed.
For this reason, I would now like to pull the main focus away from the blog, but nevertheless try to keep it somewhat more active than before.&lt;/p&gt;

&lt;h2 id=&quot;the-new-website&quot;&gt;The new website&lt;/h2&gt;

&lt;p&gt;So what remains, what changes and what has yet to come?&lt;br /&gt;
It remains my website, but its purpose has now shifted towards presenting myself. I also no longer liked my previous design, it was too sterile, too empty. The current one, although still simple, is more elegant in my opinion.&lt;br /&gt;
I no longer wished to fall back on frameworks, which, no matter how far they can be configured, are always recognisable, I wanted to create something of my own.&lt;br /&gt;
In addition, I decided a while ago that I do not want to know who comes to my site. Neither how nor why. Consequently, I removed all tools that provide me with statistics about this. This also saves me from having to deal with a cookie banner. No tracking, no external fonts hosted by Google and no integration of social media means no need for a banner.&lt;/p&gt;

&lt;p&gt;So what will the future bring for this website?
Since I would very much like to publish this website, both the portfolio of projects and the playlist overview are not yet ready. For the latter, the &lt;a href=&quot;https://github.com/tracktor-one/tracktor&quot; title=&quot;External Link: tracktor repository on Github&quot; target=&quot;_blank&quot;&gt;Tracktor API&lt;/a&gt; must first be completed first and then the frontend part developed.&lt;/p&gt;

&lt;p&gt;So there is still some work to be done until the site is the way I want it to be.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Bring me a time machine</title>
    <link href="https://felixdoering.com/en/blog/bring-me-a-time-machine/"/>
    <id>https://felixdoering.com/en/blog/bring-me-a-time-machine/</id>
    <published>2018-01-22T18:45:00+01:00</published>
    <updated>2022-02-14T17:00:00+01:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>I really like the idea of Apples TimeMachine backups. Plug in an external storage or even use some of your internal storage. The more convenient...</summary>
    <content type="html">&lt;p&gt;I really like the idea of Apples TimeMachine backups. Plug in an external storage or even use some of your internal storage.&lt;br /&gt;
The more convenient way is to create backups with a TimeCapsule or a TimeMachine network volume. When connected to your WiFi every hour a new backup is made.
But what if you already have a good router and a local server and want to perform backups on it?&lt;/p&gt;

&lt;p&gt;The solution: Configuring your server to emulate a TimeMachine network volume and macOS to accept an unofficial source. In my case the server runs on Ubuntu 17.04.&lt;br /&gt;
The communication runs via Netatalk. Unfortunately, the version provided by the latest version of Debian or Ubuntu is not compatible anymore so you have to build a newer version from source.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notice:&lt;/em&gt; This article is mostly a tutorial for myself in case I have to use it again. But the last post was nearly one and a half years ago, so I decided to publish this as well.&lt;/p&gt;

&lt;h2 id=&quot;preparing-the-build&quot;&gt;Preparing the build&lt;/h2&gt;

&lt;p&gt;First install the needed build dependencies:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;build-essential devscripts debhelper      &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
                 cdbs autotools-dev dh-buildinfo libdb-dev &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
                 libwrap0-dev libpam0g-dev libcups2-dev    &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
                 libkrb5-dev libltdl3-dev libgcrypt11-dev  &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
                 libcrack2-dev libavahi-client-dev         &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
                 libldap2-dev libacl1-dev libevent-dev     &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
                 d-shlibs dh-systemd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;build-from-source&quot;&gt;Build from source&lt;/h2&gt;

&lt;p&gt;Clone the Repository of the updated Netatalk version:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone https://github.com/adiknoth/netatalk-debian
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Change into the source directory and build it with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; debuild &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-uc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-us&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;install-netatalk-and-avahi-daemon&quot;&gt;Install Netatalk and Avahi Daemon&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;debuild&lt;/code&gt; command builds the packages and places them one directory above.
Only two of the three packages are needed. Install them with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dpkg &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; libatalk18-dev_3.1.10-1_amd64.deb
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dpkg &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; netatalk_3.1.10-1_amd64.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To be able to communicate with TimeMachine the Avahi Daemon is needed.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;avahi-daemon libc6-dev libnss-mdns
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;/h2&gt;

&lt;p&gt;Prepare a directory to store the backups in, e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/Backup/TimeMachine&lt;/code&gt; and chown it to the user who will be used to authenticate.&lt;/p&gt;

&lt;p&gt;Some changes have to be made in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/netatalk/afp.conf&lt;/code&gt;.&lt;br /&gt;
To mimic a TimeCapsule add to the [GLOBAL] Section at the top&lt;/p&gt;

&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;mimicmodel&lt;/span&gt; = &lt;span class=&quot;n&quot;&gt;TimeCapsule6&lt;/span&gt;,&lt;span class=&quot;m&quot;&gt;106&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The configuration of the “TimeCapsule” itself has to be added as well:&lt;/p&gt;

&lt;div class=&quot;language-conf highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[&lt;span class=&quot;n&quot;&gt;TimeCapsule&lt;/span&gt;]
; &lt;span class=&quot;n&quot;&gt;should&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;used&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt;?
&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;machine&lt;/span&gt; = &lt;span class=&quot;n&quot;&gt;yes&lt;/span&gt;
; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backup&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;folder&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; = /&lt;span class=&quot;n&quot;&gt;Backup&lt;/span&gt;/&lt;span class=&quot;n&quot;&gt;TimeMachine&lt;/span&gt;
; &lt;span class=&quot;n&quot;&gt;Size&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Megabyte&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;vol&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;limit&lt;/span&gt; = &lt;span class=&quot;m&quot;&gt;1000000&lt;/span&gt;
; &lt;span class=&quot;n&quot;&gt;which&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;are&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allowed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;access&lt;/span&gt;
; &lt;span class=&quot;n&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;who&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ownes&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;directory&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;valid&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; = &lt;span class=&quot;n&quot;&gt;timemachine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;starting-services-and-configure-macos-to-look-for-them&quot;&gt;Starting services and configure macOS to look for them&lt;/h2&gt;

&lt;p&gt;The last few things that have to be configured on the server is to start the services by default.&lt;/p&gt;

&lt;p&gt;Now for the last few steps required on the server. Starting the services and enable them to automatically startup on system reboot:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;netatalk.service
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl start netatalk.service
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;avahi-daemon.service
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl start avahi-daemon.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The emulated TimeCapsule is now up and running. Time to configure macOS.&lt;br /&gt;
Only one command is needed to allow unofficial Apple devices to be discovered as a TimeMachine network volume.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Server should be shown now in TimeMachine preferences now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt; This article is out of date.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Remind me of my duties</title>
    <link href="https://felixdoering.com/en/blog/remind-me-of-my-duties/"/>
    <id>https://felixdoering.com/en/blog/remind-me-of-my-duties/</id>
    <published>2016-10-27T13:07:00+02:00</published>
    <updated>2016-10-27T13:07:00+02:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>It felt like a long time ago when Felix and I built the terminal todo list tdo. But now there was time to build something new...</summary>
    <content type="html">&lt;p&gt;It felt like a long time ago when Felix and I built the terminal todo list &lt;a href=&quot;http://tdolist.de&quot; title=&quot;External Link: Projekt webseite of tdolist&quot; target=&quot;_blank&quot;&gt;tdo&lt;/a&gt;. But now there was time to build something new.&lt;br /&gt;
We started to rewrite this original Python based project in Rust a while ago, but in between I had no time to practice this language at all. So I tried to teach myself again on a different project. A notification service should be good. I want to get a mail with all my tasks.&lt;/p&gt;

&lt;p&gt;This idea was the beginning of &lt;a href=&quot;https://github.com/tdolist/tdo-notify&quot; title=&quot;External Link: tdo-notify repository on Github&quot; target=&quot;_blank&quot;&gt;tdo-notify&lt;/a&gt; a tool that can be run in a cronjob to remind you every day.
Because of the similarity between Rust and Swift it was a bit tricky to remember the correct syntax and I had some problems with the borrow checker.
All in all after reading tons of documentation of the different crates I came up with a version that worked. But there was nothing personal in it. Just the tasks, no initial sentence.&lt;/p&gt;

&lt;p&gt;How do you get the full name of the current user? It would be nice, if you have a greeting in that mail.&lt;br /&gt;
Well, you could use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;finger `whoami`&lt;/code&gt; to get the user information. The only thing is, that I don’t want to spawn a subprocess.&lt;br /&gt;
There is another method: using libc.&lt;/p&gt;

&lt;p&gt;It took me hours to get a satisfying result and I ended up with the following piece of code:&lt;/p&gt;

&lt;div class=&quot;language-rust highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;crate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;libc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_user_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;unsafe&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;libc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;geteuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;libc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;getpwuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_utf8_unchecked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;from_raw_parts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.pw_gecos&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;u8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                                           &lt;span class=&quot;nn&quot;&gt;libc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;.pw_gecos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;nf&quot;&gt;.to_vec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;Err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last_os_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nf&quot;&gt;Ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
  </entry>
  <entry>
    <title>Move it and show something else</title>
    <link href="https://felixdoering.com/en/blog/move-it/"/>
    <id>https://felixdoering.com/en/blog/move-it/</id>
    <published>2016-06-24T15:07:00+02:00</published>
    <updated>2016-06-24T15:07:00+02:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>My page is hosted on GitHub-Pages and every time I push something new Jekyll rebuilds this page and publishes it. But...</summary>
    <content type="html">&lt;h2 id=&quot;why-i-moved-away-from-github-pages&quot;&gt;Why I moved away from GitHub-Pages&lt;/h2&gt;

&lt;p&gt;My page is hosted on GitHub-Pages and every time I push something new Jekyll rebuilds this page and publishes it. But I want to move this page to &lt;a href=&quot;https://uberspace.de&quot; title=&quot;External Link: Website of the hoster uberspace&quot; target=&quot;_blank&quot;&gt;uberspace&lt;/a&gt;. The biggest reason for that is, that GitHub-Pages does not support https. Even it is not required because there is no login or form at all I would like to have a ssl protection and my mail is already hosted on uberspace. All in all there is no big deal to put both of them together. And I finally configured my Certificate for felixdoering.com.&lt;/p&gt;

&lt;h2 id=&quot;something-else&quot;&gt;Something else&lt;/h2&gt;

&lt;p&gt;That was it for the “moving” part, but what is about “show something else”?&lt;br /&gt;
I started a new project. I want to build a Rust Library (crate) for the Raspberry Pi to interact with a HD44780 LCD display. The same one I used for my Thermometer project.&lt;br /&gt;
The display has 8 data pins but there are two modes to interact with it. 8-bit mode and 4-bit mode.&lt;br /&gt;
I firstly want to focus on the 4-bit mode because you have to do much less wiring and mostly every library for other languages defaults to the 4-bit mode. For now it seems to be a little problem with the encoding. Connection and communication are working fine but the display interprets the given values wrong. I don’t know where the problem is. Probably some bits are not transmitted correctly. But for now I have to focus on other things…&lt;/p&gt;

&lt;p&gt;In fact I have two more projects I am currently working on. One of them is a fresh attempt to build an iOS App for AG DSN. The other one is to build a 10x10 RGB LED matrix with an Arduino Nano that displays some 10x10 images. Maybe there will be an animation function as well. Planing that project is really fun. And I am excited for the first time ever build something with a laser cutter.&lt;/p&gt;

&lt;p&gt;Maybe I will make an post about that individually.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Everything new</title>
    <link href="https://felixdoering.com/en/blog/everything-new/"/>
    <id>https://felixdoering.com/en/blog/everything-new/</id>
    <published>2016-04-14T12:54:40+02:00</published>
    <updated>2016-04-14T12:54:40+02:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>I wanted to have a more serious design the old one was just the standard Jekyll theme with some minor changes. It just was unready...</summary>
    <content type="html">&lt;h2 id=&quot;everything-has-a-new-look&quot;&gt;Everything has a new look&lt;/h2&gt;

&lt;p&gt;Well, at least almost. I am still the same, but my page got a new design and I decided to make my posts in English.&lt;/p&gt;

&lt;p&gt;Why?&lt;br /&gt;
There are several reasons. First of all I wanted to have a more serious design the old one was just the standard Jekyll theme with some minor changes.
It just was unready. The colors didn’t match and all in all there was no personal style at all.&lt;br /&gt;
And why in English?&lt;br /&gt;
I write my programs (almost) in English and I think it is a much cleaner look if I just do everything in the same language. Maybe I will translate my old posts, but I am not sure yet. I started and tried to translate the first ones, but then I thought it might be not a problem to see the beginnings of my blog (well, the second attempt).&lt;/p&gt;

&lt;p&gt;That’s about everything to this new page. I will continue to improve it piece by piece. For example the ‘About’ page is empty yet. This needs to be changed soon.&lt;br /&gt;
But I want to write a bit about my recent projects, too, not just the redesign of felixdoering.com:&lt;/p&gt;

&lt;h2 id=&quot;i-am-talking-to-you&quot;&gt;I am talking to you&lt;/h2&gt;

&lt;p&gt;If you know the messenger Telegram you probably know that you can use bots as well. &lt;a href=&quot;https://dummyco.de&quot; title=&quot;External Link: Blog of Felix Wittwer&quot; target=&quot;_blank&quot;&gt;Felix&lt;/a&gt; and I have written the IAmTalkingToYou Bot. But what does it do? If anyone mentions a person the bot will recognize this and send a mention to this person as well.&lt;br /&gt;
A new, yesterday implemented feature is if you write ’+1’ the bot will reply to this as well with ’&amp;lt;username of sender&amp;gt; gefällt das.’ or in case of ’-1’ ’&amp;lt;username of sender&amp;gt; gefällt das nicht.’ Yes this bot replies in German but hopefully sometime we will offer an English version as well.&lt;br /&gt;
While testing the new feature Felix has written a ‘+2’.&lt;br /&gt;
Why not let people like this just more than once? I updated the feature and from now on you can write ‘+&amp;lt;x&amp;gt;’ and you will get this reply: ‘&amp;lt;username of sender&amp;gt; gefällt das &amp;lt;x&amp;gt;-fach.’&lt;/p&gt;

&lt;h2 id=&quot;tdo---the-todo-list-for-the-terminal&quot;&gt;tdo - the TODO list for the terminal&lt;/h2&gt;

&lt;p&gt;There is another, a much bigger project, Felix and I worked on. It is called ‘tdo’. Felix wanted a simple tool for the command line to manage TODO’s and we started coding. At this point we have many features implemented and published a release on pypi. It was finished. Yes, it &lt;strong&gt;was&lt;/strong&gt;…&lt;/p&gt;

&lt;p&gt;While working as a tutor on my university I showed this tool to one of my co-tutors and he asked if he will get a notification if a TODO is open for a long time. This gave Felix and me the idea to make it even better. Because of this we made plans for a new project: &lt;em&gt;tdo-server&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When it is finished, this should be an online version of the command line tool with syncing features. But it is in really early dev and we haven’t completely decided if we really want to use Python as our language of choice or if we try some new e.g. rust.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>More frequently</title>
    <link href="https://felixdoering.com/en/blog/more-frequently/"/>
    <id>https://felixdoering.com/en/blog/more-frequently/</id>
    <published>2015-07-28T15:30:02+02:00</published>
    <updated>2015-07-28T15:30:02+02:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>Wow, that didn&apos;t hold up so well for me after all. Actually, I wanted to write a little more than I did the last time I tried to run a blog...</summary>
    <content type="html">&lt;p&gt;Wow, that didn’t hold up so well for me after all. Actually, I wanted to write a little more than I did the last time I tried to run a blog…
Apparently, I lost sight of it again at some point. Ok, so it’s time to write a post again, but where should I start?&lt;/p&gt;

&lt;p&gt;I’ve been writing a bit more recently on my “weather station”, which is made up of a Raspberry Pi Model B, a 20x4 character HD44780 LCD display and a DHT22 temperature sensor. Initially, all the pins I used were written into the code and I had the control of the display as a module. Furthermore, the DHT22 was addressed with the help of a shell script, which then wrote to a file that was eventually read out by the Python script, but this was very messy.&lt;/p&gt;

&lt;p&gt;Now, after ages, I have taken up the task again and have written an extra class for the display. Unfortunately, I couldn’t test it at the moment because I couldn’t control the display after a few tests, but I’ll do that soon! I will also add a detailed description.&lt;/p&gt;

&lt;p&gt;The sensor is now also controlled directly by the Python script, as I found a library for it directly from adafruit. Unfortunately, it is also due to the communication between the Raspberry Pi and the DHT22 that sometimes no data is received despite everything configured correctly. I have to find a way to work around this problem so that the script is not terminated. At the moment I have implemented a solution, but that is more of a hardship than a solution, it can be done much more elegantly…&lt;/p&gt;

&lt;p&gt;However, you don’t have to lift a finger to install Adafruit’s library, because if it’s not there, the script will install it by itself.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>momendlos, now</title>
    <link href="https://felixdoering.com/en/blog/momendlos-now/"/>
    <id>https://felixdoering.com/en/blog/momendlos-now/</id>
    <published>2015-06-03T19:00:00+02:00</published>
    <updated>2015-06-03T19:00:00+02:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>A new little project is making its way into my head: it&apos;s a combination of my photoblog and programming.</summary>
    <content type="html">&lt;p&gt;A new little project is making its way into my head: it’s a combination of my photoblog and programming.&lt;/p&gt;

&lt;p&gt;I have the idea to make the pictures of momendlos available to people who would like to see them and also have them as wallpaper. When at least the first part (momendlos_Desktop) is finished, it will only be possible for Mac users to have the latest photo of momendlos directly as a wallpaper or a slideshow of all available pictures.&lt;/p&gt;

&lt;p&gt;I sat down and have written a small API. Depending on which parameters are given in the GET request, a JSON file is returned with either all, a random or the most recent photo and its data.&lt;/p&gt;

&lt;p&gt;My wish is to write similar software, as soon as I am done with this one, for Windows and preferably also for iOS and Android. So all non-Mac users reading this: Maybe you’ll get a version for yourselves soon too. If you want to help me, for example with the application for Windows, you can also just write a mail to &lt;a href=&quot;mailto:mail@felixdoering.com&quot;&gt;me&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Tell me why</title>
    <link href="https://felixdoering.com/en/blog/tell-me-why/"/>
    <id>https://felixdoering.com/en/blog/tell-me-why/</id>
    <published>2015-05-05T14:03:00+02:00</published>
    <updated>2015-05-05T14:03:00+02:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>A new day, a new task. Or so I thought. As described in my previous entry, I have built an update function into my traffic plugin. But it is quite difficult...</summary>
    <content type="html">&lt;p&gt;A new day, a new task. Or so I thought. As described in my previous entry, I have built an update function into my traffic plugin. But it is quite difficult to publish new updates.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Build&lt;/li&gt;
  &lt;li&gt;Zip the build (there is no getting around these two steps)&lt;/li&gt;
  &lt;li&gt;Sign the zip&lt;/li&gt;
  &lt;li&gt;Create a release on Github and attach the zip as binaries&lt;/li&gt;
  &lt;li&gt;(at least for me) change into the gh-pages branch&lt;/li&gt;
  &lt;li&gt;Update the following in the appcast.xml:
    &lt;ul&gt;
      &lt;li&gt;Name of the new release&lt;/li&gt;
      &lt;li&gt;Version numvber&lt;/li&gt;
      &lt;li&gt;Description&lt;/li&gt;
      &lt;li&gt;Link to the zip file&lt;/li&gt;
      &lt;li&gt;set the DSA-Key (you get it from signing the zip)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Push the branch and cross your fingers that everything works&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s why I’ve been looking for a way to automate this a little bit. I mean, it wouldn’t be difficult, if you have the information from step 6 to just insert it with the help of a little script. The unpleasant thing is that you would have to do all the steps before that manually so that you have all the information for it.
It’s nice that Github exists! Because somehow you always find people who have already built something for it out of the same problem.
Maybe not directly the same problem now, but it helps in general anyway!
&lt;a href=&quot;https://github.com/aktau/github-release&quot; title=&quot;External Link: github-release repository on Github&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;github-release&lt;/strong&gt;&lt;/a&gt; by aktau is a tool that can create releases for Github via the command line and can also attach binaries. This should make it fairly easy to write everything in a somewhat larger script.&lt;/p&gt;

&lt;p&gt;The signing of the zip file is also only a command, which receives the zip as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$1&lt;/code&gt; and the private key for encryption as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$2&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl dgst -sha1 -binary &amp;lt; &quot;$1&quot; | $openssl dgst -dss1 -sign &quot;$2&quot; | $openssl enc -base64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;You could simply cache the string that is returned and you have the next piece of information. The link that exists (only after the release) can be “guessed” because it always has the format https://github.com/&amp;lt;username&amp;gt;/&amp;lt;repo&amp;gt;/releases/download/&amp;lt;version tag&amp;gt;/&amp;lt;file&amp;gt;.
So it looks like I’ll set about doing it via this method.&lt;/p&gt;

&lt;p&gt;But now let’s take a quick look at the rather strange title of this post:
I tried to do the whole thing somehow with the help of a webhook from Github, but failed already with the configuration of the Apache webserver on my server. It would be really nice if the documentation of apache2 would state somewhere that since version 2.4 you have to activate the CGI module manually via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a2enmod cgi&lt;/code&gt; until anything happens.
It is really nice to have detailed documentation, but then it should also be up to date.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Automated is better</title>
    <link href="https://felixdoering.com/en/blog/automated-is-better/"/>
    <id>https://felixdoering.com/en/blog/automated-is-better/</id>
    <published>2015-05-03T22:03:00+02:00</published>
    <updated>2015-05-03T22:03:00+02:00</updated>
    <author>
      <name>Felix Döring</name>
    </author>
    <summary>Yesterday evening I found a bug in my traffic plugin for the dormitory internet in the display of the traffic still available. So I set to work to fix it as quickly as possible so...</summary>
    <content type="html">&lt;p&gt;Yesterday evening I found a bug in my traffic plugin for the dormitory internet in the display of the traffic still available. So I set to work to fix it as quickly as possible so that it can be used reliably again.&lt;/p&gt;

&lt;p&gt;Apart from myself, I only know two people who use this tool, &lt;a href=&quot;https://github.com/JustusAdam&quot; title=&quot;External link: Profile of Justus Adam on Github&quot; target=&quot;_blank&quot;&gt;Justus&lt;/a&gt; and &lt;a href=&quot;https://github.com/kiliankoe&quot; title=&quot;External link: Profile of Kilian Költzsch on Github&quot; target=&quot;_blank&quot;&gt;Kilian&lt;/a&gt;. So I also contacted both of them that I have released a new version.
Just for fun, Justus brought up the idea that an autoupdater could be included in the next version. I have to admit that idea had crossed my mind before, because it’s pretty much the only way to distribute updates to a wider audience.&lt;/p&gt;

&lt;p&gt;My first idea was to make a request to the Github API every minute, similar to retrieving the traffic, to see what the latest release is. However, that would have been quite a back and forth. Thanks to Kilian I found a nice framework, &lt;a href=&quot;http://sparkle-project.org&quot; title=&quot;External link: Sparkle project website&quot; target=&quot;_blank&quot;&gt;Sparkle&lt;/a&gt;, which makes it relatively easy to distribute updates.&lt;/p&gt;

&lt;p&gt;As is always the case when you don’t know what you’re talking about, it was quite complicated to read this manual, especially if you’ve never really worked with frameworks in XCode before, like I have. In the end, however, I got it right.&lt;/p&gt;

&lt;p&gt;For those who also want to use this framework, here is a little tip:
By default, Sparke always checks &lt;strong&gt;CFBundleVersion&lt;/strong&gt; as the version number, which in XCode is the &lt;strong&gt;Build&lt;/strong&gt; and &lt;em&gt;not&lt;/em&gt; the version.&lt;/p&gt;
</content>
  </entry>
</feed>
