<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title></title>
    <description>Welcome to my personal blog, where I share experiences on coding, reverse engineering, travel and culture</description>
    <link>https://daanmiddendorp.com//</link>
    <atom:link href="https://daanmiddendorp.com//feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 09 Mar 2025 06:33:34 +0000</pubDate>
    <lastBuildDate>Sun, 09 Mar 2025 06:33:34 +0000</lastBuildDate>
    <generator>Jekyll v3.9.5</generator>
    
      <item>
        <title>The Simple Beauty of Vietnamese Language</title>
        <description>&lt;p&gt;After studying Vietnamese language for five months, I think that it is a challenging language to learn for Westerners. Especially the vocabulary with different tones is extremely hard to master: &lt;em&gt;Bạn bận bán bàn bẩn không?&lt;/em&gt;, if you want to ask if someone is busy selling dirty tables. All joking apart, other features of this language are way simpler than you might expect. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20241114_0026_01.jpg&quot; alt=&quot;Saigon Central Post Office in Ho Chi Minh City&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20241114_0026_01.jpg 895w,    /assets/responsive-images/1080/20241114_0026_01.jpg 1080w,    /assets/responsive-images/1440/20241114_0026_01.jpg 1440w,    /assets/responsive-images/1790/20241114_0026_01.jpg 1790w,    /assets/responsive-images/2685/20241114_0026_01.jpg 2685w,    /assets/responsive-images/3580/20241114_0026_01.jpg 3580w, /./images/photos/20241114_0026_01.jpg 5198w&quot; /&gt;
&lt;small&gt;Saigon Central Post Office in Ho Chi Minh City&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;it-is-an-isolating-language&quot;&gt;It is an isolating language&lt;/h3&gt;
&lt;p&gt;Isolating languages do not combine words. Vietnamese words can therefore not be broken up into different components with different meanings. Moreover, Vietnamese words are very short, as they mostly consist of only one syllable.&lt;/p&gt;

&lt;p&gt;The longest word in Vietnamese language is seven letters long. It is &lt;em&gt;“nghiêng”&lt;/em&gt; which means “inclined” or “to lean”, in case you are wondering.&lt;/p&gt;

&lt;p&gt;The nature of an isolating language enables the Vietnamese to use multiple words in order to address things. This makes it easy to understand definitions of unfamiliar phrases and it is fun to guess their origin! Some examples I would like to share:&lt;/p&gt;

&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;thang&lt;/th&gt;
      &lt;th&gt;ladder&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;thang bộ&lt;/td&gt;
      &lt;td&gt;ladder to walk on (stairs)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;thang máy&lt;/td&gt;
      &lt;td&gt;ladder machine (elevator)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;thang cuốn&lt;/td&gt;
      &lt;td&gt;rolling ladder (escalator)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;xe&lt;/th&gt;
      &lt;th&gt;vehicle&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;xe máy&lt;/td&gt;
      &lt;td&gt;vehicle machine (motorbike)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;xe đạp&lt;/td&gt;
      &lt;td&gt;vehicle to kick (bicycle)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;xe hơi&lt;/td&gt;
      &lt;td&gt;vehicle with gas (car)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;xe lưa&lt;/td&gt;
      &lt;td&gt;vehicle with fire (train)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;xe khách&lt;/td&gt;
      &lt;td&gt;vehicle with customers (bus)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;forget-about-plural-forms&quot;&gt;Forget about plural forms&lt;/h3&gt;
&lt;p&gt;There is no need to use plural forms of nouns. Ordering one or many beers, the Vietnamese like to keep things simple.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;bia&lt;/th&gt;
      &lt;th&gt;beer&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;không bia&lt;/td&gt;
      &lt;td&gt;zero beer/no beer/without beer&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;một bia&lt;/td&gt;
      &lt;td&gt;one beer&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;hai bia&lt;/td&gt;
      &lt;td&gt;two beers&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;hai mươi bia&lt;/td&gt;
      &lt;td&gt;two ten (20) beers&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;However, in some situations, it might be desirable to clarify if you mean one or many. In these cases, you add &lt;em&gt;các&lt;/em&gt;, which is a pluraliser.&lt;/p&gt;
&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;chị&lt;/th&gt;
      &lt;th&gt;miss&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;chào chị&lt;/td&gt;
      &lt;td&gt;hello miss&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;chào &lt;em&gt;các&lt;/em&gt; chị&lt;/td&gt;
      &lt;td&gt;hello multiple miss (hello ladies)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;no-grammatical-conjugation&quot;&gt;No grammatical conjugation&lt;/h3&gt;
&lt;p&gt;In Vietnamese grammar, it does not matter who did something at what point in time. Just add a word to indicate if it happened in the past or is going to happen in the future.&lt;/p&gt;

&lt;div class=&quot;table_less_margin&quot;&gt;Tomorrow, I am going to the supermarket&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Ngày mai &lt;br /&gt; Tomorrow&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;tội &lt;br /&gt; I&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;sẽ &lt;br /&gt; (future)&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;đị&lt;/strong&gt; &lt;br /&gt; &lt;strong&gt;go&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;sieu thị&lt;/strong&gt; &lt;br /&gt; &lt;strong&gt;supermarket&lt;/strong&gt; &lt;br /&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;table_less_margin&quot;&gt;Yesterday, they went to the supermarket&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
      &lt;th style=&quot;text-align: left&quot;&gt;&lt;!-- --&gt;&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;Hom qua &lt;br /&gt; Yesterday&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;họ &lt;br /&gt; they&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;đã &lt;br /&gt; (past)&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;&lt;strong&gt;đị&lt;/strong&gt; &lt;br /&gt; &lt;strong&gt;go&lt;/strong&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: left&quot;&gt;&lt;strong&gt;sieu thị&lt;/strong&gt; &lt;br /&gt; &lt;strong&gt;supermarket&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;As you can see, the verb &lt;em&gt;đị&lt;/em&gt; (to go) does not change at all. Maybe someone needs to show the Germans.&lt;/p&gt;

&lt;h3 id=&quot;numbers-tell-the-tale&quot;&gt;Numbers tell the tale&lt;/h3&gt;
&lt;p&gt;Names can be confusing. Especially in Dutch, where we have two sequential months named &lt;em&gt;juni&lt;/em&gt; and &lt;em&gt;juli&lt;/em&gt;. The Vietnamese must have been thinking: why would we come up with names if we can be using numbers anyway?&lt;/p&gt;

&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;tháng&lt;/th&gt;
      &lt;th&gt;month&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;tháng một&lt;/td&gt;
      &lt;td&gt;month one (January)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;tháng hai&lt;/td&gt;
      &lt;td&gt;month two (February)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;tháng ba&lt;/td&gt;
      &lt;td&gt;month three (March)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;…&lt;/td&gt;
      &lt;td&gt;…&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;thứ&lt;/th&gt;
      &lt;th&gt;indication of rank&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;thứ hai&lt;/td&gt;
      &lt;td&gt;the second (Monday)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;thứ ba&lt;/td&gt;
      &lt;td&gt;the third (Tuesday)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;…&lt;/td&gt;
      &lt;td&gt;…&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;some-interesting-but-less-convenient-features&quot;&gt;Some interesting, but less convenient features&lt;/h3&gt;

&lt;p&gt;The fact that surprised me most is that there are some basic words missing in Vietnamese language. There is no separate word for the color &lt;em&gt;green&lt;/em&gt; and the color &lt;em&gt;blue&lt;/em&gt;. This got me into a weird situation when I hired a graphic designer that (apparently) used Google Translate to translate my requests. The Vietnamese just add more words to make their meaning clear.&lt;/p&gt;

&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;xanh&lt;/th&gt;
      &lt;th&gt;blue/green&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;xanh da trời&lt;/td&gt;
      &lt;td&gt;blue/green like the sky (blue)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;xanh lá&lt;/td&gt;
      &lt;td&gt;blue/green like a leaf (green)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;On the other hand, I find it interesting that are phrases in Vietnamese that do not exist in English or other languages that I am familiar with. For example, they use different phrases for grandparents on each side of the familiy.&lt;/p&gt;

&lt;div class=&quot;fixed_table&quot;&gt;&lt;/div&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;ông bà&lt;/th&gt;
      &lt;th&gt;grandparents&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;ông bà ngoại&lt;/td&gt;
      &lt;td&gt;grandparents outside (mother’s side)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ông bà nội&lt;/td&gt;
      &lt;td&gt;grandparents inside (father’s side)&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The traditional idea in Vietnam is that if a couple gets married, the wife moves in to the family house of the husband. Therefore, the grandparents inside the house are always the parents of the husband. The outside grandparents are the parents of the wife.&lt;/p&gt;

&lt;!-- 

Nevertheless, this only works with true Vietnamese words. If a phrase originates from another language, it becomes much harder to guess the origin. Even the Vietnamese themselves are mostly not able to explain the different components.

One example of a word with a Chinese origin: *consulate*


| lãnh | sự | quán | Vietnamese |
|:-:|:-:|:-:|:--|
| lǐng | shì | guǎn | Chinese Phonetic |
| 領 |  事 | 館 | Traditional Chinese |
| leader | of things | building | |


 --&gt;

</description>
        <pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//culture/2025/02/13/the-simple-beauty-of-vietnamese-language</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//culture/2025/02/13/the-simple-beauty-of-vietnamese-language</guid>
        
        
        <category>culture</category>
        
      </item>
    
      <item>
        <title>Why Brussels is Probably the Worst Place to Live as a Diplomatic Spouse</title>
        <description>&lt;p&gt;It has been one year since I moved to Brussels as (first time) spouse of a diplomat. The experience as a +1 has been both fascinating and disappointing at the same time. I don’t seem to be the only one having difficulties adapting to this way of life. A couple of papers mention the challenges of Brussels in particular. Let me take you through the characteristics explaining why Brussels is not like every other expatriate location. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20231007_124503.jpg&quot; alt=&quot;Belgian flag under the Cinquantenaire Arcade: 100&amp;lt;sup&amp;gt;th&amp;lt;/sup&amp;gt; birthday of the Military Museum&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20231007_124503.jpg 895w,    /assets/responsive-images/1080/20231007_124503.jpg 1080w,    /assets/responsive-images/1440/20231007_124503.jpg 1440w,    /assets/responsive-images/1790/20231007_124503.jpg 1790w,    /assets/responsive-images/2685/20231007_124503.jpg 2685w,    /assets/responsive-images/3580/20231007_124503.jpg 3580w, /./images/photos/20231007_124503.jpg 4032w&quot; /&gt;
&lt;small&gt;Belgian flag under the Cinquantenaire Arcade: 100&lt;sup&gt;th&lt;/sup&gt; birthday of the Military Museum&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;lack-of-representational-entertaining&quot;&gt;Lack of Representational Entertaining&lt;/h3&gt;
&lt;p&gt;Representational entertaining is about hosting events that provide guests the opportunity to experience the country’s culture: meetings, activities, as well as formal dinners and receptions.&lt;/p&gt;

&lt;p&gt;The approach towards representational entertaining differs between multi- and bilateral representations, as they have different functions to fulfil. One of the main responsibilities of bilateral posts is to be an enabler of cultural exchange. At smaller and geographically focused embassies, promoting national culture is like being on a parade: regular events with all kinds of obligations&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;At multilateral delegations, not so much. Most of Brussels diplomatic bubble is bound to EU institutions and other international organisations. All with a common goal that exceeds the national level. Especially, the EU is about promoting the European thought, resulting in the suppression of national differences&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, the amount of representational entertaining is low in Brussels. Especially after the financial crisis of 2008, spouses are expected to participate in even fewer events. Meaning that they are being free most of the time. As this is an important part of the role of a diplomatic spouse, some feel excluded, diminished and isolated&lt;sup id=&quot;fnref:2:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h3 id=&quot;low-esprit-de-corps&quot;&gt;Low Esprit de Corps&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Esprit de corps&lt;/em&gt;, or morale, is about the capacity of a group to believe in an institution or common goal. At smaller embassies, the relationships with others take on the pattern of a kind of extended family. As spouses rely on their environment for their identity&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, this is especially important for subjects where spouses cooperate. Think of ensuring the well-being of other spouses and welcoming newcomers&lt;sup id=&quot;fnref:1:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Representations in Brussels are mostly large and fragmented. The lack of a common goal, being scattered around the city in huge offices, makes it difficult to feel a strong &lt;em&gt;esprit de corps&lt;/em&gt;. No camaraderie results in spouses feeling cast out on their own.&lt;/p&gt;

&lt;p&gt;Some countries, such as the UK and the US, introduced the paid role of &lt;em&gt;community liaison officer&lt;/em&gt; in Brussels to fill this gap&lt;sup id=&quot;fnref:1:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. A position that is responsible for the  welfare, well-being and morale of staff and dependents. A role that is generally fulfilled by a spouse.&lt;/p&gt;

&lt;h3 id=&quot;poor-work-life-balance&quot;&gt;Poor Work-life Balance&lt;/h3&gt;
&lt;p&gt;For diplomats, a role in Brussels is far from easy going. It is a stressful environment as capital cities keep a close eye on what happens in Brussels. With 60-hour work weeks not being uncommon, there is little room for a healthy work-life balance or quality time&lt;sup id=&quot;fnref:2:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. On top of that, military representations work with classified material, which makes working from home hardly an option.&lt;/p&gt;

&lt;p&gt;Such an environment attracts ambitious hard-working diplomats, often without an accompanying partner or family. This contributes to the effect of the lack of camaraderie for spouses even more.&lt;/p&gt;

&lt;h3 id=&quot;too-easy-to-live&quot;&gt;Too easy to live&lt;/h3&gt;
&lt;p&gt;Living in Brussels is easy from a practical point of view. As it is so close to other capital cities (The Hague, London and Paris are all reachable within two hours), it keeps it possible to visit friends and family back home on a regular basis.&lt;/p&gt;

&lt;p&gt;Moreover, for many diplomat families arriving in Brussels there is no severe culture shock or feeling really different, whatsoever&lt;sup id=&quot;fnref:1:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Nobody is really forced into building a new social life or finding your way in a new culture.&lt;/p&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;But what’s good about being the spouse of a diplomat in Brussels? Apparently, there is something attractive, as a lot of diplomats tend to return to Brussels at some point in their career.&lt;/p&gt;

&lt;p&gt;I think that Brussels is especially hard in the beginning if you start without a network and without a social circle. 
Some seasoned diplomatic spouses, however, refer to the points mentioned above as an advantage. Coming from a city where you were expected to join a party almost every day of the week, having some privacy and tranquillity in Brussels could be the right choice.&lt;/p&gt;

&lt;p&gt;Feel free to reach out to me if you have comments or suggestions. I am open to discussions at &lt;a href=&quot;mailto:daan@daanmiddendorp.com&quot;&gt;daan@daanmiddendorp.com&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Black, A. (1995). The changing culture of diplomatic spouses: Some fieldnotes from Brussels. Diplomacy and Statecraft, 6(1), 196-222. &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt; &lt;a href=&quot;#fnref:1:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; &lt;a href=&quot;#fnref:1:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt; &lt;a href=&quot;#fnref:1:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;4&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Hendry, A. (1998). From Parallel to Dual Careers: Diplomatic Spouses in the European Context. &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt; &lt;a href=&quot;#fnref:2:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;2&lt;/sup&gt;&lt;/a&gt; &lt;a href=&quot;#fnref:2:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;sup&gt;3&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;Gudmundsdottir, S., Gudlaugsson, T. O., &amp;amp; Adalsteinsson, G. D. (2019). The diplomatic spouse: Relationships between adjustment, social support and satisfaction with life. Journal of Global Mobility: The Home of Expatriate Management Research, 7(1), 103-122. &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 12 Oct 2023 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//culture/2023/10/12/why-brussels-is-probably-the-worst-place-to-live-as-a-diplomatic-spouse</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//culture/2023/10/12/why-brussels-is-probably-the-worst-place-to-live-as-a-diplomatic-spouse</guid>
        
        
        <category>culture</category>
        
      </item>
    
      <item>
        <title>Advanced Catch-All Mailboxes: Parsing (BCC) Recipient with Cloudflare Email Workers</title>
        <description>&lt;p&gt;I am a big fan of catch-all mailboxes. They enable me to use a unique email address for every service that demands my personal information. By doing so, I know exactly who is emailing me or who leaked my email address. Let’s explore how we can elevate this concept on a technical level with programmable email routing. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; As &lt;a href=&quot;https://gist.github.com/landgenoot/07e3d64e3f3db49c5075e5428cbc87eb?permalink_comment_id=5450382#gistcomment-5450382&quot;&gt;@uwolfer&lt;/a&gt; pointed out, it is possible to use the &lt;code&gt;message.to&lt;/code&gt; directly to read out the BCC value. &lt;code&gt;message.to&lt;/code&gt; contains the envelope value &lt;code&gt;RFC5321.RcptTo&lt;/code&gt;, not &lt;code&gt;RFC5322.To&lt;/code&gt;. This simplifies the neccesary code.&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230629_105602.jpg&quot; alt=&quot;An offline Belgian mailbox&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230629_105602.jpg 895w,    /assets/responsive-images/1080/20230629_105602.jpg 1080w,    /assets/responsive-images/1440/20230629_105602.jpg 1440w,    /assets/responsive-images/1790/20230629_105602.jpg 1790w,    /assets/responsive-images/2685/20230629_105602.jpg 2685w,    /assets/responsive-images/3580/20230629_105602.jpg 3580w, /./images/photos/20230629_105602.jpg 4032w&quot; /&gt;
&lt;small&gt;An offline Belgian mailbox&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;h3 id=&quot;catch-all-format&quot;&gt;Catch-all Format&lt;/h3&gt;
&lt;p&gt;The format that I use for unique email addresses consist of the name of the company, a flag, and my custom domain name. E.g. &lt;em&gt;ecorp-d@example.com&lt;/em&gt; tells me that &lt;strong&gt;ECorp&lt;/strong&gt; emails me to my personal mailbox, which is set by &lt;strong&gt;-d&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In order to get this to work, I had different wonky solutions over the past few years. One of them was forwarding all emails to a Gmail account and setting up filters in order to make the emails end up in the right mailbox.&lt;/p&gt;

&lt;p&gt;These solutions have one major drawback: you can only filter on the &lt;em&gt;from&lt;/em&gt; and &lt;em&gt;to&lt;/em&gt; header of the email. The actual receiving email address is not always present in those headers: when receiving a Blind Carbon Copy (BCC) or emails from a mailing list. Therefore, utilising filters and forwards is far from ideal for this goal.&lt;/p&gt;

&lt;h3 id=&quot;cloudflare-email-workers&quot;&gt;Cloudflare Email Workers&lt;/h3&gt;
&lt;p&gt;Cloudflare offers a service called Email Routing. It basically enables you to create and manage email addresses and forwards for a domain name that is managed by Cloudflare.&lt;/p&gt;

&lt;p&gt;Additionally, they started a public beta a couple of months ago with so-called Email Workers. Email Workers enable you to programmatically handle emails. A piece of JavaScript decides what should happen with an incoming email: forward somewhere or reject.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;allowList&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;friend@example.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;bob@example.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;allowList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;from&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setReject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Address not allowed&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;inbox@corp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;w&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;/figure&gt;

&lt;p&gt;&lt;small&gt;Example from Cloudflare on how to allow only certain senders&lt;/small&gt;&lt;/p&gt;

&lt;h3 id=&quot;parsing-received-by--for&quot;&gt;Parsing Received by … for&lt;/h3&gt;
&lt;p&gt;Now comes the tricky part. Cloudflare offers a nice &lt;a href=&quot;https://developers.cloudflare.com/workers/runtime-apis/email-event/&quot;&gt;EmailEvent API&lt;/a&gt; that can be called from JavaScript. However, this only allows for querying the &lt;em&gt;from&lt;/em&gt; and &lt;em&gt;to&lt;/em&gt; headers directly. In order to fetch more information, the raw email needs to be parsed manually.&lt;/p&gt;

&lt;p&gt;The header that tells us the actual recipient looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; Received: by mail-vk1-f194.google.com with SMTP id 71f...
 for &amp;lt;ecorp-d@example.com&amp;gt;; Wed, 28 Jun 2023 04:30:15 -0700 (PDT)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Every mail server that processes the email adds such a header. &lt;code&gt;message.headers.get(&quot;received&quot;)&lt;/code&gt; is, however, not capable of returning all of them. It only returns the last occurrence of Received, but the first one is needed. The entire source of the email must be parsed using the following regex.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;parseRecipient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\b(?&amp;lt;=for &amp;lt;).+@example.com(?=&amp;gt;;)\b/g&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&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;/figure&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;(?&amp;lt;=for &amp;lt;):&lt;/strong&gt; This is a positive lookbehind expression that checks if the pattern is preceded by “for &amp;lt;”.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;.+@example.com:&lt;/strong&gt; This pattern matches one or more characters followed by “@example.com”.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;(?=&amp;gt;;):&lt;/strong&gt; This is a positive lookahead expression that checks if the pattern is followed by “&amp;gt;;”.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;source-code&quot;&gt;Source code&lt;/h3&gt;
&lt;p&gt;I have brought it all together in a Gist, with blacklist functionality that can be hosted as a .txt file somewhere.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://gist.github.com/landgenoot/07e3d64e3f3db49c5075e5428cbc87eb&quot;&gt;cloudflare-email-worker-recipient-flag-parser.js on Gist&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 28 Jun 2023 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//tech/2023/06/28/parsing-bcc-recipient-with-cloudflare-email-workers</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//tech/2023/06/28/parsing-bcc-recipient-with-cloudflare-email-workers</guid>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Cycling Through Western Europe: A Scenic Journey to Rome - Photo Album included</title>
        <description>&lt;p&gt;Western Europe is very cyclable. With a high density of paved roads and accommodations, it is easy to travel long distances by bike. From May 1&lt;sup&gt;st&lt;/sup&gt; onwards, I gave it a shot and started cycling in the direction of Rome. This post enables me to keep track of the journey and maintain a photo album. &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230514_085811.jpg&quot; alt=&quot;Me at the Switzerland / Liechtenstein / Austia tri-border area&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230514_085811.jpg 895w,    /assets/responsive-images/1080/20230514_085811.jpg 1080w,    /assets/responsive-images/1440/20230514_085811.jpg 1440w,    /assets/responsive-images/1790/20230514_085811.jpg 1790w,    /assets/responsive-images/2685/20230514_085811.jpg 2685w,    /assets/responsive-images/3580/20230514_085811.jpg 3580w, /./images/photos/20230514_085811.jpg 4032w&quot; /&gt;
&lt;small&gt;Me at the Switzerland / Liechtenstein / Austia tri-border area&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;routing&quot;&gt;Routing&lt;/h3&gt;
&lt;p&gt;There are multiple roads that lead to Rome. One of the routes is designed in 1991 by &lt;a href=&quot;https://www.cyclingeurope.nl/routes/rome/index.php&quot;&gt;Cycling Europe&lt;/a&gt;. Another one is the &lt;a href=&quot;https://en.eurovelo.com/ev5&quot;&gt;Eurovelo5&lt;/a&gt;, which is co-funded by the COSME programme of the European Union. However, routing is not something that is fixed. You need to have available accommodation across the route, you might want to see specific things.&lt;/p&gt;

&lt;p&gt;In my opinion, it is best to use these routes as a guideline, but plan the individual legs using &lt;a href=&quot;https://cycle.travel&quot;&gt;cycle.travel&lt;/a&gt;. Cycle.travel is a very good bicycle route planner that takes a couple of things into account:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Existing cycling routes, for example: it takes the EV5 when convenient.&lt;/li&gt;
  &lt;li&gt;Traffic information: It uses traffic data to determine which roads are not busy.&lt;/li&gt;
  &lt;li&gt;Better scenery: It analyses landforms and prefers scenic roads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/mapimage20230605.jpeg&quot; alt=&quot;My journey&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/mapimage20230605.jpeg 895w,    /assets/responsive-images/1080/mapimage20230605.jpeg 1080w,    /assets/responsive-images/1440/mapimage20230605.jpeg 1440w,    /assets/responsive-images/1790/mapimage20230605.jpeg 1790w,    /assets/responsive-images/2685/mapimage20230605.jpeg 2685w,    /assets/responsive-images/3580/mapimage20230605.jpeg 3580w, /./images/photos/mapimage20230605.jpeg 5152w&quot; /&gt;
&lt;small&gt;My journey&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;gear&quot;&gt;Gear&lt;/h3&gt;
&lt;p&gt;For me, it is about the journey and not about sport. You won’t get better scenic views or better weather if you are riding a 3000+ euros bike. I am cycling on a 13-year-old city bike with an 8-speed internal gear, which has a packed weight of 40 kilos in total. Even climbing 1500 meters in one day in the Alps is doable.&lt;/p&gt;

&lt;h3 id=&quot;quality-of-roads&quot;&gt;Quality of roads&lt;/h3&gt;
&lt;p&gt;Belgium and Italy are the worst in terms of bicycle-friendliness. Even in Belgium, with their fully developed EV5, you will find “paved” roads with enormous holes in it that become dangerous if you oversee them. Italy it as you’d expect it. Dedicated bicycle lanes are rare. So it is either riding the main road together with trucks, or choosing an unpaved road. The latter roads are not recommended, as you don’t know their quality on beforehand. Multiple times, I had to cycle all the way back because the road was inaccessible due to mud or overgrown plants.&lt;/p&gt;

&lt;h3 id=&quot;accommodation&quot;&gt;Accommodation&lt;/h3&gt;
&lt;p&gt;Most of the overnight stays were in hostels and bed-and-breakfasts. During national holidays or long weekends, it becomes a struggle to find a place to stay. Hotels and hostels tend to sell out or become heavily overpriced. I tried to stay within a total budget of 56 EUR per day, which is possible, but not very comfortable. It means that you have to stay at campsites when hostels are fully booked and go through Switzerland really quick. Due to the weather conditions, I only stayed at a campsite once. For the hostels, I paid between 25-35 EUR (50 in CH), mostly including breakfast.&lt;/p&gt;

&lt;h3 id=&quot;photo-album&quot;&gt;Photo album&lt;/h3&gt;
&lt;p&gt;The following pictures give an impression of what to expect during this journey.&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230501_162423.jpg&quot; alt=&quot;76 km - The Maas river near Namur, Belgium&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230501_162423.jpg 895w,    /assets/responsive-images/1080/20230501_162423.jpg 1080w,    /assets/responsive-images/1440/20230501_162423.jpg 1440w,    /assets/responsive-images/1790/20230501_162423.jpg 1790w,    /assets/responsive-images/2685/20230501_162423.jpg 2685w,    /assets/responsive-images/3580/20230501_162423.jpg 3580w, /./images/photos/20230501_162423.jpg 4032w&quot; /&gt;
&lt;small&gt;76 km - The Maas river near Namur, Belgium&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230503_111404.jpg&quot; alt=&quot;204 km - Landscape in the Ardennes, Belgium&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230503_111404.jpg 895w,    /assets/responsive-images/1080/20230503_111404.jpg 1080w,    /assets/responsive-images/1440/20230503_111404.jpg 1440w,    /assets/responsive-images/1790/20230503_111404.jpg 1790w,    /assets/responsive-images/2685/20230503_111404.jpg 2685w,    /assets/responsive-images/3580/20230503_111404.jpg 3580w, /./images/photos/20230503_111404.jpg 4032w&quot; /&gt;
&lt;small&gt;204 km - Landscape in the Ardennes, Belgium&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230503_194557.jpg&quot; alt=&quot;265 km - Luxembourg, Luxembourg&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230503_194557.jpg 895w,    /assets/responsive-images/1080/20230503_194557.jpg 1080w,    /assets/responsive-images/1440/20230503_194557.jpg 1440w,    /assets/responsive-images/1790/20230503_194557.jpg 1790w,    /assets/responsive-images/2685/20230503_194557.jpg 2685w,    /assets/responsive-images/3580/20230503_194557.jpg 3580w, /./images/photos/20230503_194557.jpg 4032w&quot; /&gt;
&lt;small&gt;265 km - Luxembourg, Luxembourg&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230507_114937.jpg&quot; alt=&quot;463 km - Vosges, Regional Park&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230507_114937.jpg 895w,    /assets/responsive-images/1080/20230507_114937.jpg 1080w,    /assets/responsive-images/1440/20230507_114937.jpg 1440w,    /assets/responsive-images/1790/20230507_114937.jpg 1790w,    /assets/responsive-images/2685/20230507_114937.jpg 2685w,    /assets/responsive-images/3580/20230507_114937.jpg 3580w, /./images/photos/20230507_114937.jpg 4032w&quot; /&gt;
&lt;small&gt;463 km - Vosges, Regional Park&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230508_151233.jpg&quot; alt=&quot;590 km - Colmar, France&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230508_151233.jpg 895w,    /assets/responsive-images/1080/20230508_151233.jpg 1080w,    /assets/responsive-images/1440/20230508_151233.jpg 1440w,    /assets/responsive-images/1790/20230508_151233.jpg 1790w,    /assets/responsive-images/2685/20230508_151233.jpg 2685w,    /assets/responsive-images/3580/20230508_151233.jpg 3580w, /./images/photos/20230508_151233.jpg 4032w&quot; /&gt;
&lt;small&gt;590 km - Colmar, France&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230510_134043.jpg&quot; alt=&quot;636 km - Mulhouse, France&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230510_134043.jpg 895w,    /assets/responsive-images/1080/20230510_134043.jpg 1080w,    /assets/responsive-images/1440/20230510_134043.jpg 1440w,    /assets/responsive-images/1790/20230510_134043.jpg 1790w,    /assets/responsive-images/2685/20230510_134043.jpg 2685w,    /assets/responsive-images/3580/20230510_134043.jpg 3580w, /./images/photos/20230510_134043.jpg 3977w&quot; /&gt;
&lt;small&gt;636 km - Mulhouse, France&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230516_153707.jpg&quot; alt=&quot;788 km - Diessenhofen, Switzerland&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230516_153707.jpg 895w,    /assets/responsive-images/1080/20230516_153707.jpg 1080w,    /assets/responsive-images/1440/20230516_153707.jpg 1440w,    /assets/responsive-images/1790/20230516_153707.jpg 1790w,    /assets/responsive-images/2685/20230516_153707.jpg 2685w,    /assets/responsive-images/3580/20230516_153707.jpg 3580w, /./images/photos/20230516_153707.jpg 3890w&quot; /&gt;
&lt;small&gt;788 km - Diessenhofen, Switzerland&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230513_150159.jpg&quot; alt=&quot;950 km - Rhine at the Switzerland / Austria border&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230513_150159.jpg 895w,    /assets/responsive-images/1080/20230513_150159.jpg 1080w,    /assets/responsive-images/1440/20230513_150159.jpg 1440w,    /assets/responsive-images/1790/20230513_150159.jpg 1790w,    /assets/responsive-images/2685/20230513_150159.jpg 2685w,    /assets/responsive-images/3580/20230513_150159.jpg 3580w, /./images/photos/20230513_150159.jpg 4032w&quot; /&gt;
&lt;small&gt;950 km - Rhine at the Switzerland / Austria border&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230514_121807.jpg&quot; alt=&quot;983 km - Swiss Alps&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230514_121807.jpg 895w,    /assets/responsive-images/1080/20230514_121807.jpg 1080w,    /assets/responsive-images/1440/20230514_121807.jpg 1440w,    /assets/responsive-images/1790/20230514_121807.jpg 1790w,    /assets/responsive-images/2685/20230514_121807.jpg 2685w,    /assets/responsive-images/3580/20230514_121807.jpg 3580w, /./images/photos/20230514_121807.jpg 4032w&quot; /&gt;
&lt;small&gt;983 km - Swiss Alps&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230515_092046.jpg&quot; alt=&quot;1104 km - Splügenpass at 1000 meters altitude&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230515_092046.jpg 895w,    /assets/responsive-images/1080/20230515_092046.jpg 1080w,    /assets/responsive-images/1440/20230515_092046.jpg 1440w,    /assets/responsive-images/1790/20230515_092046.jpg 1790w,    /assets/responsive-images/2685/20230515_092046.jpg 2685w,    /assets/responsive-images/3580/20230515_092046.jpg 3580w, /./images/photos/20230515_092046.jpg 4032w&quot; /&gt;
&lt;small&gt;1104 km - Splügenpass at 1000 meters altitude&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230515_120931.jpg&quot; alt=&quot;1127 km - Splügenpass at 2100 meters altitude&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230515_120931.jpg 895w,    /assets/responsive-images/1080/20230515_120931.jpg 1080w,    /assets/responsive-images/1440/20230515_120931.jpg 1440w,    /assets/responsive-images/1790/20230515_120931.jpg 1790w,    /assets/responsive-images/2685/20230515_120931.jpg 2685w,    /assets/responsive-images/3580/20230515_120931.jpg 3580w, /./images/photos/20230515_120931.jpg 4032w&quot; /&gt;
&lt;small&gt;1127 km - Splügenpass at 2100 meters altitude&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230515_130825.jpg&quot; alt=&quot;1153 km - Italian (sunny) side of the Splügenpass&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230515_130825.jpg 895w,    /assets/responsive-images/1080/20230515_130825.jpg 1080w,    /assets/responsive-images/1440/20230515_130825.jpg 1440w,    /assets/responsive-images/1790/20230515_130825.jpg 1790w,    /assets/responsive-images/2685/20230515_130825.jpg 2685w,    /assets/responsive-images/3580/20230515_130825.jpg 3580w, /./images/photos/20230515_130825.jpg 4032w&quot; /&gt;
&lt;small&gt;1153 km - Italian (sunny) side of the Splügenpass&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230515_163711.jpg&quot; alt=&quot;1200 km - Como lake, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230515_163711.jpg 895w,    /assets/responsive-images/1080/20230515_163711.jpg 1080w,    /assets/responsive-images/1440/20230515_163711.jpg 1440w,    /assets/responsive-images/1790/20230515_163711.jpg 1790w,    /assets/responsive-images/2685/20230515_163711.jpg 2685w,    /assets/responsive-images/3580/20230515_163711.jpg 3580w, /./images/photos/20230515_163711.jpg 4032w&quot; /&gt;
&lt;small&gt;1200 km - Como lake, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230518_100657.jpg&quot; alt=&quot;1225 km - Courtyard in Colico, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230518_100657.jpg 895w,    /assets/responsive-images/1080/20230518_100657.jpg 1080w,    /assets/responsive-images/1440/20230518_100657.jpg 1440w,    /assets/responsive-images/1790/20230518_100657.jpg 1790w,    /assets/responsive-images/2685/20230518_100657.jpg 2685w,    /assets/responsive-images/3580/20230518_100657.jpg 3580w, /./images/photos/20230518_100657.jpg 4032w&quot; /&gt;
&lt;small&gt;1225 km - Courtyard in Colico, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230515_202224.jpg&quot; alt=&quot;1232 km - Ferry in Menaggio, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230515_202224.jpg 895w,    /assets/responsive-images/1080/20230515_202224.jpg 1080w,    /assets/responsive-images/1440/20230515_202224.jpg 1440w,    /assets/responsive-images/1790/20230515_202224.jpg 1790w,    /assets/responsive-images/2685/20230515_202224.jpg 2685w,    /assets/responsive-images/3580/20230515_202224.jpg 3580w, /./images/photos/20230515_202224.jpg 4032w&quot; /&gt;
&lt;small&gt;1232 km - Ferry in Menaggio, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230521_084918.jpg&quot; alt=&quot;1380 km - Brescia, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230521_084918.jpg 895w,    /assets/responsive-images/1080/20230521_084918.jpg 1080w,    /assets/responsive-images/1440/20230521_084918.jpg 1440w,    /assets/responsive-images/1790/20230521_084918.jpg 1790w,    /assets/responsive-images/2685/20230521_084918.jpg 2685w,    /assets/responsive-images/3580/20230521_084918.jpg 3580w, /./images/photos/20230521_084918.jpg 4032w&quot; /&gt;
&lt;small&gt;1380 km - Brescia, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230521_210636.jpg&quot; alt=&quot;1437 km - Garda, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230521_210636.jpg 895w,    /assets/responsive-images/1080/20230521_210636.jpg 1080w,    /assets/responsive-images/1440/20230521_210636.jpg 1440w,    /assets/responsive-images/1790/20230521_210636.jpg 1790w,    /assets/responsive-images/2685/20230521_210636.jpg 2685w,    /assets/responsive-images/3580/20230521_210636.jpg 3580w, /./images/photos/20230521_210636.jpg 4032w&quot; /&gt;
&lt;small&gt;1437 km - Garda, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230523_095719.jpg&quot; alt=&quot;1580 km - Ducal Palace, Mantua, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230523_095719.jpg 895w,    /assets/responsive-images/1080/20230523_095719.jpg 1080w,    /assets/responsive-images/1440/20230523_095719.jpg 1440w,    /assets/responsive-images/1790/20230523_095719.jpg 1790w,    /assets/responsive-images/2685/20230523_095719.jpg 2685w,    /assets/responsive-images/3580/20230523_095719.jpg 3580w, /./images/photos/20230523_095719.jpg 3961w&quot; /&gt;
&lt;small&gt;1580 km - Ducal Palace, Mantua, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230525_133602.jpg&quot; alt=&quot;1625 km - Rocchetta Mattei, Bologna, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230525_133602.jpg 895w,    /assets/responsive-images/1080/20230525_133602.jpg 1080w,    /assets/responsive-images/1440/20230525_133602.jpg 1440w,    /assets/responsive-images/1790/20230525_133602.jpg 1790w,    /assets/responsive-images/2685/20230525_133602.jpg 2685w,    /assets/responsive-images/3580/20230525_133602.jpg 3580w, /./images/photos/20230525_133602.jpg 4032w&quot; /&gt;
&lt;small&gt;1625 km - Rocchetta Mattei, Bologna, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230526_112647.jpg&quot; alt=&quot;1637 km - Suviana Lake, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230526_112647.jpg 895w,    /assets/responsive-images/1080/20230526_112647.jpg 1080w,    /assets/responsive-images/1440/20230526_112647.jpg 1440w,    /assets/responsive-images/1790/20230526_112647.jpg 1790w,    /assets/responsive-images/2685/20230526_112647.jpg 2685w,    /assets/responsive-images/3580/20230526_112647.jpg 3580w, /./images/photos/20230526_112647.jpg 4032w&quot; /&gt;
&lt;small&gt;1637 km - Suviana Lake, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230527_153145.jpg&quot; alt=&quot;1689 km - Tuscany, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230527_153145.jpg 895w,    /assets/responsive-images/1080/20230527_153145.jpg 1080w,    /assets/responsive-images/1440/20230527_153145.jpg 1440w,    /assets/responsive-images/1790/20230527_153145.jpg 1790w,    /assets/responsive-images/2685/20230527_153145.jpg 2685w,    /assets/responsive-images/3580/20230527_153145.jpg 3580w, /./images/photos/20230527_153145.jpg 4032w&quot; /&gt;
&lt;small&gt;1689 km - Tuscany, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230528_134339.jpg&quot; alt=&quot;1809 km - Barberino di Mugello, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230528_134339.jpg 895w,    /assets/responsive-images/1080/20230528_134339.jpg 1080w,    /assets/responsive-images/1440/20230528_134339.jpg 1440w,    /assets/responsive-images/1790/20230528_134339.jpg 1790w,    /assets/responsive-images/2685/20230528_134339.jpg 2685w,    /assets/responsive-images/3580/20230528_134339.jpg 3580w, /./images/photos/20230528_134339.jpg 4032w&quot; /&gt;
&lt;small&gt;1809 km - Barberino di Mugello, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230529_185018.jpg&quot; alt=&quot;1844 km - Florence, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230529_185018.jpg 895w,    /assets/responsive-images/1080/20230529_185018.jpg 1080w,    /assets/responsive-images/1440/20230529_185018.jpg 1440w,    /assets/responsive-images/1790/20230529_185018.jpg 1790w,    /assets/responsive-images/2685/20230529_185018.jpg 2685w,    /assets/responsive-images/3580/20230529_185018.jpg 3580w, /./images/photos/20230529_185018.jpg 4032w&quot; /&gt;
&lt;small&gt;1844 km - Florence, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230602_060833.jpg&quot; alt=&quot;2014 km - Fabro, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230602_060833.jpg 895w,    /assets/responsive-images/1080/20230602_060833.jpg 1080w,    /assets/responsive-images/1440/20230602_060833.jpg 1440w,    /assets/responsive-images/1790/20230602_060833.jpg 1790w,    /assets/responsive-images/2685/20230602_060833.jpg 2685w,    /assets/responsive-images/3580/20230602_060833.jpg 3580w, /./images/photos/20230602_060833.jpg 4032w&quot; /&gt;
&lt;small&gt;2014 km - Fabro, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230603_194256.jpg&quot; alt=&quot;2317 km - Spanish steps, Rome, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230603_194256.jpg 895w,    /assets/responsive-images/1080/20230603_194256.jpg 1080w,    /assets/responsive-images/1440/20230603_194256.jpg 1440w,    /assets/responsive-images/1790/20230603_194256.jpg 1790w,    /assets/responsive-images/2685/20230603_194256.jpg 2685w,    /assets/responsive-images/3580/20230603_194256.jpg 3580w, /./images/photos/20230603_194256.jpg 4032w&quot; /&gt;
&lt;small&gt;2317 km - Spanish steps, Rome, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230606_105641.jpg&quot; alt=&quot;2317 km - Galleria nazionale d'arte moderna e contemporanea, Rome, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230606_105641.jpg 895w,    /assets/responsive-images/1080/20230606_105641.jpg 1080w,    /assets/responsive-images/1440/20230606_105641.jpg 1440w,    /assets/responsive-images/1790/20230606_105641.jpg 1790w,    /assets/responsive-images/2685/20230606_105641.jpg 2685w,    /assets/responsive-images/3580/20230606_105641.jpg 3580w, /./images/photos/20230606_105641.jpg 4032w&quot; /&gt;
&lt;small&gt;2317 km - Galleria nazionale d’arte moderna e contemporanea, Rome, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230603_193407.jpg&quot; alt=&quot;2317 km - View from Villa Borghese, Rome, Italy&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230603_193407.jpg 895w,    /assets/responsive-images/1080/20230603_193407.jpg 1080w,    /assets/responsive-images/1440/20230603_193407.jpg 1440w,    /assets/responsive-images/1790/20230603_193407.jpg 1790w,    /assets/responsive-images/2685/20230603_193407.jpg 2685w,    /assets/responsive-images/3580/20230603_193407.jpg 3580w, /./images/photos/20230603_193407.jpg 4032w&quot; /&gt;
&lt;small&gt;2317 km - View from Villa Borghese, Rome, Italy&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;The combination of having one greater goal, being active and performing a daily routine makes you feel extremely healthy. Both mentally and physically.&lt;/p&gt;

&lt;p&gt;The most relaxing part is that there is no negative sentiment against regular cyclists. You can both reach destinations that are in the middle of nowhere and park in a crowded historic city center. Something that is impossible with public transport or a car.&lt;/p&gt;
</description>
        <pubDate>Tue, 16 May 2023 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//travel/2023/05/16/bicycle-travel-across-europe</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//travel/2023/05/16/bicycle-travel-across-europe</guid>
        
        
        <category>travel</category>
        
      </item>
    
      <item>
        <title>Exploring Greece's innovative fight against tax evasion: QR codes, snitching apps, and VAT lotteries</title>
        <description>&lt;p&gt;Macedonia, the northern part of Greece, offers a beautiful green landscape with a crystal clear Mediterranean Sea. But that is not the only thing that I find interesting. After spending a couple of days here and visiting some local restaurants and coffee shops, the QR code printed on every receipt got my curiosity. Let’s find out how the Greek are fighting tax evasion.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230403_144634.jpg&quot; alt=&quot;Example receipt with QR code&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230403_144634.jpg 895w,    /assets/responsive-images/1080/20230403_144634.jpg 1080w,    /assets/responsive-images/1440/20230403_144634.jpg 1440w,    /assets/responsive-images/1790/20230403_144634.jpg 1790w,    /assets/responsive-images/2685/20230403_144634.jpg 2685w,    /assets/responsive-images/3580/20230403_144634.jpg 3580w, /./images/photos/20230403_144634.jpg 4032w&quot; /&gt;
&lt;small&gt;Example receipt with QR code&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;tracking-every-transaction&quot;&gt;Tracking every transaction&lt;/h3&gt;
&lt;p&gt;Scanning the QR code points you to a URL (&lt;a href=&quot;https://www1.aade.gr/tameiakes/myweb/q1.php?SIG=DLK2200480200007907F0699D3567B0E62BEFB523B83509B334F917D82830.30&quot;&gt;example from below&lt;/a&gt;) of the Independent Public Revenue Authority (AADE). Surprisingly, this page contains all the VAT details about that particular purchase, which is submitted electronically in real time by the merchant. The amount per tax rate and even the amount of liters and type of petrol if it is a fuel purchase. By scanning this QR code, the customer can therefore know for sure that VAT has been paid.&lt;/p&gt;

&lt;p&gt;I have some mixed feelings about his type of control. From a taxpayer perspective, it is genius to have such a system in a country that suffers from tax evasion and corruption. You are 100% sure that the taxes you are paying will be received by the tax authority and do not end up in the pockets of the merchant. But it is no guarantee that it will be invested in the country itself.&lt;/p&gt;

&lt;p&gt;Moreover, tracking every purchase that is being made in an entire country leads to extra data points that might violate privacy when combined with others. Known as the Background Knowledge Attack: “Oh, we saw you go to the hospital. We found only one cash payment with the amount of the price of an STD test at the moment you left.”&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20230331_125959.jpg&quot; alt=&quot;Miniature roadside chapel in Chalkidi region&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20230331_125959.jpg 895w,    /assets/responsive-images/1080/20230331_125959.jpg 1080w,    /assets/responsive-images/1440/20230331_125959.jpg 1440w,    /assets/responsive-images/1790/20230331_125959.jpg 1790w,    /assets/responsive-images/2685/20230331_125959.jpg 2685w,    /assets/responsive-images/3580/20230331_125959.jpg 3580w, /./images/photos/20230331_125959.jpg 3900w&quot; /&gt;
&lt;small&gt;Miniature roadside chapel in Chalkidi region&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;snitching-app&quot;&gt;Snitching app&lt;/h3&gt;
&lt;p&gt;Why would the average tax payer care about this QR code if he or she could also benefit from tax evasion? Agreeing on a cash deal might benefit the customer significantly, as the VAT rate in Greece is quite high compared to other European countries (24%).&lt;/p&gt;

&lt;p&gt;The tax authority has run a campaign (even at airports aiming for tourists) to call for refusal to pay if no valid receipt is issued&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Furthermore, they introduced an app called &lt;a href=&quot;https://www.aade.gr/appodixi&quot;&gt;Appodixi&lt;/a&gt;, which can be used to verify receipts. But this app has one very interesting gimmick: if you scanned an invalid receipt, you can report it directly to the tax authority from within the app. If it turns out to be tax fraud and the merchant gets fined, you will get a reward up to 10 times the value of your receipt with a maximum of 2000 EUR&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;h3 id=&quot;the-vat-lottery&quot;&gt;The VAT lottery&lt;/h3&gt;
&lt;p&gt;But there is more! Apparently, there exists such a thing as a VAT lottery. Basically, every resident in Greece is taking part in a lottery when paying for goods and services by debit or credit card.&lt;/p&gt;

&lt;p&gt;Every euro spent anywhere in the country is a ticket in the lottery. By the end of each month, 1000 residents will win the VAT lottery and receive a prize of 1000 EUR in their bank account, costing the government 1M EUR per month in prize money.&lt;/p&gt;

&lt;p&gt;When I heard about this, I first thought it was a joke. But this is apparently something that is also implemented in Malta, Portugal and Slovakia&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. It has a couple of benefits: you need to pay by card, which makes it harder to evade tax by the merchant. You won’t be taking part in the lottery if you spend your unreported cash. Moreover, spending more will increase your chance of winning, which might be a stimulus for the economy as a whole.&lt;/p&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;It is interesting to see that these entertaining ideas are actually viable. Maybe it is also cultural difference, but I think that if someone comes up with the idea of a VAT lottery in a more economically stable country, there is no chance that this will get enough support. Why would you reward someone who is doing their duty by paying their taxes?&lt;/p&gt;

&lt;p&gt;Furthermore, I have no idea about the effectiveness in terms of the whole economy. It could be the case that large scaled corruption still happens and this only affects simple merchants and everyday people.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.aade.gr/apodixi&quot;&gt;https://www.aade.gr/apodixi&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.in.gr/2022/12/19/english-edition/bounty-tax-evasion-reward-greeks-denouncing-appodixi-app/&quot;&gt;https://www.in.gr/2022/12/19/english-edition/bounty-tax-evasion-reward-greeks-denouncing-appodixi-app/&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://taxation-customs.ec.europa.eu/system/files/2016-09/taxation_paper_51.pdf&quot;&gt;https://taxation-customs.ec.europa.eu/system/files/2016-09/taxation_paper_51.pdf&lt;/a&gt; &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Mon, 03 Apr 2023 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//financial/2023/04/03/exploring-greeces-innovative-fight-against-tax-evasion</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//financial/2023/04/03/exploring-greeces-innovative-fight-against-tax-evasion</guid>
        
        
        <category>financial</category>
        
      </item>
    
      <item>
        <title>Improve NPO Start Experience without Smart Devices: Kodi, Retrospect, and IPTV Manager</title>
        <description>&lt;p&gt;The Dutch public broadcast corporation (NPO) is quite good at offering digital solutions to watch publicly funded TV shows. It offers a wide variety of different apps for different platforms, such as smart TV’s, mobile devices and browser. For watching television, I am happily using a 2009 Samsung smart TV. And yes, you guessed it, the smart-component is completely useless in 2023. Let’s see what we can do to enhance the NPO Start Live TV experience, but without smart devices, cable TV providers and big tech.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h3 id=&quot;kodi&quot;&gt;Kodi&lt;/h3&gt;
&lt;p&gt;Formerly known as XBMC, Kodi is the open source entertainment system that runs on different platforms. By installing it on a Raspberry PI, you will have a great entertainment ecosystem that plays all types of video’s, can be controlled with the remote of your television and is able to run  add-ons. Playing video’s is nice, but the add-ons will enable you to interact with all kinds of digital services.&lt;/p&gt;

&lt;p&gt;Pick any video-on-demand provider or website, and the odds are high that someone wrote an add-on for that particular service. Just to give you an example: Youtube, Netflix, HBO, FOX sports, Dumpert and NPO Start are all available. NPO Start support is part of the &lt;a href=&quot;https://github.com/retrospect-addon/plugin.video.retrospect&quot;&gt;Retrospect&lt;/a&gt; plugin&lt;/p&gt;

&lt;h3 id=&quot;retrospect&quot;&gt;Retrospect&lt;/h3&gt;
&lt;p&gt;Retrospect did a very good job at implementing the streams of national broadcasting companies, such as The Netherlands, Belgium, Great Britain, Norway and Sweden. It offers an easy to navigate menu structure and the possibility to watch live channels.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;full-img&quot; src=&quot;/images/retrospect.jpg&quot; /&gt;
&lt;br /&gt;
However, Retrospect is currently not integrated with the IPTV-component in Kodi. Therefore, the experience of zapping through channels and browsing the EPG could be improved.&lt;/p&gt;

&lt;h3 id=&quot;iptv-manager&quot;&gt;IPTV Manager&lt;/h3&gt;
&lt;p&gt;Kodi also offers linear TV functionality, this enables you to plug in a USB DVB receiver and watch live television. However, in the current era of streaming services, DVB is not that relevant any more. Some countries, such as Belgium, have already phased out DVB-T.&lt;/p&gt;

&lt;p&gt;Fortunately, there is also an add-on available that enables us to watch IPTV-streams on Kodi. This add-on, which is called &lt;a href=&quot;https://github.com/kodi-pvr/pvr.iptvsimple&quot;&gt;IPTV Simple&lt;/a&gt;, allows us to open a m3u8 playlist file containing video streams and zap through them. But for using this add-on, you need to have a static file containing these stream URL’s. It is not that convenient if you need to create those files yourself.&lt;/p&gt;

&lt;p&gt;This is where &lt;a href=&quot;https://github.com/add-ons/service.iptv.manager&quot;&gt;IPTV Manager&lt;/a&gt; jumps in, IPTV Manager does exactly what you might expect. It controls the streams and EPG of IPTV Simple programmatically. It can even query existing video add-ons for support and fetch the streams and EPG.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;full-img&quot; src=&quot;/images/iptvmanager.jpg&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is exactly what we need. We have already an add-on that allows us to stream live NPO channels, and we do have add-ons that allow us to integrate it with the IPTV functionality. So basically, we meet all the criteria to make it work, but we need to make the add-ons talk to each other.&lt;/p&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;/assets/js/mermaid.min.js&quot;&gt;&lt;/script&gt;

&lt;div class=&quot;mermaid center&quot;&gt;
graph TD;
    id1[IPTV Simple]--&amp;gt;Kodi;
    id2[IPTV Manager]--&amp;gt;id1[IPTV Simple];
    Retrospect--&amp;gt;Kodi;
    Retrospect-.-&amp;gt;id2[IPTV Manager];
    id2[IPTV Manager]-.-&amp;gt;Retrospect;
&lt;/div&gt;
&lt;p&gt;&lt;small&gt;The dotted lines are the parts that are still missing in Retrospect.&lt;/small&gt;&lt;/p&gt;

&lt;h3 id=&quot;building-the-thing&quot;&gt;Building the thing&lt;/h3&gt;
&lt;p&gt;It took me a couple of hours to dive into the Kodi ecosystem, as I had never worked on an Kodi or an add-on before. I was really surprised that it is all just Python that is being executed. You can modify the source code of any installed add-on by just editing the source files under &lt;code&gt;.kodi/addons/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, I could cheat by looking at the &lt;a href=&quot;https://github.com/add-ons/plugin.video.vrt.nu/blob/master/resources/lib/iptvmanager.py&quot;&gt;implementation&lt;/a&gt; of a similar add-on. By browsing around, I figured out that the hardest part would probably to integrate the functionality nicely into Retrospect. For example, in Retrospect it is not as straight forwarded to start a livestream by a URI. You need to mark a certain MediaItem as favourite first, before you can start it immediately.&lt;/p&gt;

&lt;p&gt;Before starting working on the PR, I contacted Bas to ask him if he would be open to such functionality. He is really nice and helpful and gave me some advice on the actual implementation.&lt;/p&gt;

&lt;p&gt;After some struggling with existing web scrapers, I found out that there is an actual API that we can make use of. After a couple of hours, I got the basic functionality working.&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;full-img&quot; src=&quot;/images/npo.png&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;I am still busy finishing up the functionality, but what I think is great is that I am already using it on a daily basis. The experience of watching linear television is more polished right now and the possibility of browsing the EPG just like when using a television receiver is very convenient. Moreover, I think it is nice to make yourself familiar with different types of (open source) software projects. It helps you to get better at understanding something that someone else built.&lt;/p&gt;
</description>
        <pubDate>Sun, 19 Feb 2023 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//tech/2023/02/19/npo-start-kodi-iptv-integration</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//tech/2023/02/19/npo-start-kodi-iptv-integration</guid>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Maximising privacy and control: Rooting and Installing Valetudo on Roborock Vacuum Cleaners</title>
        <description>&lt;p&gt;I am not a fan of “smart” devices; they try to bring some upper class luxury to the middle class using technology. For example, vacuum cleaners: those who cannot afford a cleaning lady, can probably afford a robot vacuum cleaner that does some vacuuming for you. However, these devices come with the cost of privacy as everything it does do is sent back to the vendor. Is it possible to have both the privacy and cheap comfort?&lt;!--more--&gt;&lt;/p&gt;

&lt;h3 id=&quot;roborock&quot;&gt;Roborock&lt;/h3&gt;
&lt;p&gt;Somewhere around 2020, I dived into the world of robot vacuum cleaners, because someone in the family was interested in buying one. On internet forums, several brands and types were discussed. Back then there was one clear winner: the &lt;strong&gt;Roborock S5 Max&lt;/strong&gt;. Capable of vacuuming, mopping and able to create a map of your home using LIDAR technology. After buying such a vacuum cleaner, it did everything that it promised extremely well.&lt;/p&gt;

&lt;p&gt;Now that I have moved to a larger single floor apartment, I was also in the market for a vacuum cleaner. So why not buy a robot cleaner as well? Without much research, I bought the exact same model, which worked like expected.&lt;/p&gt;

&lt;h3 id=&quot;privacy&quot;&gt;Privacy&lt;/h3&gt;
&lt;p&gt;The vacuum cleaner does a great job at cleaning. Unfortunately, you need to install an app and be connected to the internet at all times to control it.&lt;/p&gt;

&lt;p&gt;All the communications with the robot goes through the Roborock servers, which might become useful if you want to control your robot when you are away. For me, this rarely happens. The rest of the time, it takes a long time to connect to the robot, which is quite frustrating.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there a way to get around this data gathering, unstable and privacy violating ecosystem?&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;
  &lt;img src=&quot;/images/roborock.png&quot; style=&quot;max-height: 800px; width: auto; margin: 0 auto;
    padding: 0.6em 0;&quot; /&gt;
  &lt;small&gt;Official app&lt;/small&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;valetudo&quot;&gt;Valetudo&lt;/h3&gt;
&lt;p&gt;Back in 2020, I was not aware about some work going on to reverse engineer and modify those vacuum cleaners. Sören Beye, an engineer from Germany, created a “cloud replacement” named Valetudo&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;What it basically does, it redirects the requests that the robot sends to vendor, to a local service on the device instead. This makes it possible to control the robot within your local network without being dependent on some web service hosted abroad out of your control.&lt;/p&gt;

&lt;div class=&quot;center&quot;&gt;
  &lt;img src=&quot;/images/valetudo.png&quot; /&gt;
  &lt;small&gt;Control the robot from the browser&lt;/small&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;rooting&quot;&gt;Rooting&lt;/h3&gt;
&lt;p&gt;Valetudo supports a range of vacuum cleaners, but you need to gain root access to the robot first in order to install it. Root access makes it possible to run arbitrairy software.&lt;/p&gt;

&lt;p&gt;In the past, there have been several ways to get root access to those Roborock vacuum cleaners. However, most of them have been patched by the vendor and everything is based on the connection with the cloud right now.&lt;/p&gt;

&lt;p&gt;One of the rooting methods that still works is by tricking the motherboard into a low-level subroutine called &lt;em&gt;FEL&lt;/em&gt;, which is intended for device recovery. It allows the device to boot any operating system from USB and bypassing the NAND memory. Dennis Giese, a PhD-student, created a service to build images that can root devices using the FEL-method&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. These images basically boot up the board, enable SSH-access and some other configuration changes.&lt;/p&gt;

&lt;p&gt;The hardest part is getting your vacuum cleaner into this FEL-method. In order to do so, you need to get access to the motherboard and connect a pin (TPA17) with the ground while booting it. This means that you basically need to tear it apart completely, which is not without risk. This &lt;a href=&quot;https://www.youtube.com/watch?v=0vLa4-iikzM&quot;&gt;video&lt;/a&gt; helped me a lot, but it will take you about an afternoon to screw it apart and together again.&lt;/p&gt;

&lt;h3 id=&quot;installing-cloud-replacement&quot;&gt;Installing cloud replacement&lt;/h3&gt;
&lt;p&gt;Once you have rooted the device, the installing procedure of the cloud replacement is pretty straight forwarded. Valetudo is packed as one single binary containing everything, which you need to download to the internal storage (you might need to clear some logs to free up space, as the robot logs everything). After rebooting you can control the robot by browsing to its IP-address.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;It is a great feeling that the device is mine now. I can do anything with it now and even talk to the API directly. Moreover, tearing the device apart and putting it together gives me the confidence to repair it myself, if that would be necessary. The spare parts of this vacuum cleaner are widely available.&lt;/p&gt;

&lt;p&gt;Detailed instructions on how to root those devices and install valetudo can be found &lt;a href=&quot;https://valetudo.cloud/pages/installation/roborock.html#fel&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://github.com/Hypfer/Valetudo&quot;&gt;https://github.com/Hypfer/Valetudo&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://builder.dontvacuum.me&quot;&gt;https://builder.dontvacuum.me&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Sun, 08 Jan 2023 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//tech/2023/01/08/rooting-a-vacuum-cleaner</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//tech/2023/01/08/rooting-a-vacuum-cleaner</guid>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Unlocking a Public Parking Garage with Android Auto: Reverse Engineering Official App</title>
        <description>&lt;p&gt;The gate of the public parking garage that I am renting can be opened with an app. However, unlocking a phone, searching the app, choosing the particular parking and pressing “enter by car”. Isn’t that convenient while driving. Let’s see if we can upgrade this user experience.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;A couple of weeks ago, I got inspired by greenluigi1’s article&lt;sup id=&quot;fnref:1&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; about getting root access to the infotainment system of Hyundai vehicles. This made me want to find a fun and useful project with some reverse engineering again. As I started renting a parking lot last week, I stumbled upon this opportunity to create something cool.&lt;/p&gt;

&lt;h3 id=&quot;the-parking-app&quot;&gt;The parking app&lt;/h3&gt;
&lt;p&gt;The app that is being provided by the parking company works by simply logging in and pressing a button, which opens the gate for you. There is a validation built in that checks whether you are within a certain distance to the parking garage. I am not sure why they have built in this check, as they are also offering a fallback option by calling a phone number and typing in a code.&lt;/p&gt;

&lt;p&gt;With my background as a software engineer, I expected it to be quite a basic app that does some authentication and makes an API-request. Luckily, it turned out to be exactly that. After decompiling the app using &lt;a href=&quot;http://www.javadecompilers.com/apk&quot;&gt;javadecompiles&lt;/a&gt;, I found a service interface which had all the possible API endpoints listed, including a GET method &lt;code&gt;/api/v3/gate/{gate}/open&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next step is finding out where that web server is located. Running a search query with the domain name of the company brought me to a &lt;code&gt;BuildConfig.java&lt;/code&gt; that had a &lt;code&gt;BASE_URL&lt;/code&gt; like &lt;code&gt;https://api-v3.parking-company.com/&lt;/code&gt;. Bingo! Let’s see what we have over there.&lt;/p&gt;

&lt;div class=&quot;center&quot;&gt;
  &lt;img src=&quot;/images/laravel.png&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;That looks like a standard Laravel project, nothing too exciting here. Let’s try one of our previously found API-endpoints. As expected, they result in an error, which is obvious, as there had to be some authentication mechanism. One of the endpoints is &lt;code&gt;oauth/token&lt;/code&gt;, which indicates that oauth is being used. As this is a standard method, it is built in into Postman. The &lt;code&gt;CLIENT_ID&lt;/code&gt; and &lt;code&gt;CLIENT_SECRET&lt;/code&gt; were both also in the &lt;code&gt;BuildConfig.java&lt;/code&gt; which makes it super easy.  Filling in my account details got me an access token immediately, which is also automatically applied to the API requests Postman makes. Let’s see if we can fetch some account information from the API!&lt;/p&gt;

&lt;div class=&quot;center&quot;&gt;
  &lt;img src=&quot;/images/userbytoken.png&quot; /&gt;
  &lt;small&gt;Postman fetching user details by access token.&lt;/small&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;That returns all my account data, including license plate and phone number. However, it does not tell my anything about my subscription or the gates that I am allowed to open. Let’s give  &lt;code&gt;/api/v3/user/{user}/access&lt;/code&gt; a try. This lists my subscription nicely, including the gates that are available.&lt;/p&gt;

&lt;div class=&quot;center&quot;&gt;
  &lt;img src=&quot;/images/access.png&quot; /&gt;
  &lt;small&gt;Postman fetching access details.&lt;/small&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;These are the numbers we need, so let’s see if we can open the gate programmatically. By looking at the service interface, we need to provide a couple of other details, such as: user id, purchase id, coordinates and way. The coordinates are needed to check if we are not too far away from the garage. So we will give the parking company a peace of mind and reassure that we are allowed to open the gate by passing the exact location that got from the garage details. I am not able to find what the &lt;code&gt;way&lt;/code&gt; parameter should be from the code. However, I guessed &lt;code&gt;in&lt;/code&gt;  and that seems to be working.&lt;/p&gt;

&lt;div class=&quot;center&quot;&gt;
  &lt;img src=&quot;/images/gate.png&quot; /&gt;
  &lt;small&gt;Postman opening the gate.&lt;/small&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Active&lt;/em&gt;, that seems like a success. I didn’t check if the gate actually opened, but I was pretty certain that it would work so I started immediately with the next step: more convenience.&lt;/p&gt;

&lt;h3 id=&quot;android-auto&quot;&gt;Android auto&lt;/h3&gt;
&lt;p&gt;Every car with an In-Vehicle Infotainment (IVI) system that is being produced right now, even a Fiat 500, seems to support Android Auto.  What I really like about Android Auto, is that it does not matter how crappy the infotainment system is, you will always get the same experience.&lt;/p&gt;

&lt;p&gt;So, now we are able to make an API-request programmatically, it should be easy to create an Android Auto app that makes this request once you open it, right?&lt;/p&gt;

&lt;p&gt;Full of enthusiasm, I cloned an Android Auto &lt;a href=&quot;https://github.com/android/car-samples&quot;&gt;hello-world example&lt;/a&gt;. A nice feature of Postman is that you can copy the request into multiple programming languages, including Java OkHttp. That makes life even easier. The access token within the request is valid for 365 days, so I didn’t bother about implementing authentication logic.&lt;/p&gt;

&lt;p&gt;Spend one or two hours fine-tuning the app, so that it closes the activity automatically after opening. Tested it in the emulator, where it was working!&lt;/p&gt;

&lt;video autoplay=&quot;autoplay&quot; loop=&quot;loop&quot; class=&quot;full-img&quot; muted=&quot;&quot;&gt;
  &lt;source src=&quot;/videos/opengarage-emulator.webm&quot; type=&quot;video/webm&quot; /&gt;
  &lt;source src=&quot;/videos/opengarage-emulator.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-pitfall&quot;&gt;The pitfall&lt;/h3&gt;
&lt;p&gt;On my next trip, I stepped into my car full of excitement and drove to the exit of the garage.  However… the app was nowhere to be seen. Reboot, restart car. Other device. No app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It turns out that Google is fighting the 3rd party app community&lt;/strong&gt;, as they think it is insecure to have any type of app to run on your car’s head unit. As a developer, you cannot test an Android Auto app on a real car&lt;sup id=&quot;fnref:2&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:2&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. The only way to test it, according to Google, is to upload it to the play store in an Alpha channel. Using this method, Google wil test if your app does not distract during driving and fits the Android Auto ecosystem before releasing it.&lt;/p&gt;

&lt;p&gt;I am not confident that Google will accept my app. Moreover, my account details are now hard-coded into the app, so I don’t want to upload it somewhere.&lt;/p&gt;

&lt;h3 id=&quot;fooling-google&quot;&gt;Fooling Google&lt;/h3&gt;
&lt;p&gt;When Google prevents you from doing something, the general answer is rooting. Rooting a device gives you back all the freedom to do whatever you want with your own hardware. As I rooted and flashed many devices in the past, I am certainly familiar with the pros and cons of doing so. Nowadays, I think the need for rooting is minimal, as the standard Android ecosystem has improved heavily over the last decade. Moreover, rooting my device (and also other devices that I want to run the app on) would require a lot of work, not be convenient and introduce security risks.&lt;/p&gt;

&lt;p&gt;Luckily, the good old XDA developers forum is also active around creating modifications for the Android Auto ecosystem&lt;sup id=&quot;fnref:3&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:3&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.  The information around there is a little bit fragmented. However, one app called Fermata Media Player&lt;sup id=&quot;fnref:4&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:4&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;, which enables you to watch YouTube on an Android Auto headunit, had some interesting information. As this application is not available on the Play Store, they list a couple of methods to install this third-party software.&lt;/p&gt;

&lt;p&gt;One of the methods to get third-party applications working without root is using an app called &lt;a href=&quot;https://gitlab.com/annexhack/king-installer&quot;&gt;KingInstaller&lt;/a&gt;. This app simply lets you select and install an untrusted APK-file, which magically shows up on Android Auto. How does this particular app work if it does not need root? Let’s take a look at the &lt;a href=&quot;https://gitlab.com/annexhack/king-installer/-/blob/master/app/src/main/java/com/example/kinginstaller/MainActivity.java&quot;&gt;source code&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;android.intent.action.INSTALL_PACKAGE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putExtra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;android.intent.extra.NOT_UNKNOWN_SOURCE&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putExtra&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;android.intent.extra.INSTALLER_PACKAGE_NAME&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;com.android.vending&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In Android terms, an Intent is simply an action that is being performed. So as you can see, the android package installer is being called with the APK as data.&lt;/p&gt;

&lt;p&gt;Moreover, it adds two extra parameters &lt;code&gt;NOT_UNKNOWN_SOURCE&lt;/code&gt; and &lt;code&gt;INSTALLER_PACKAGE_NAME&lt;/code&gt;.  The first parameter specifies that the application should be treated as coming from the app invoking the intent &lt;sup id=&quot;fnref:5&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:5&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;5&lt;/a&gt;&lt;/sup&gt;, which is KingInstaller in this case. Secondly, the installer package name is set to &lt;code&gt;com.android.vending&lt;/code&gt;. This package is also known as the Google Play store.&lt;/p&gt;

&lt;p&gt;It turns out that this is the general way to find out which app store installed the app, from within the app itself &lt;sup id=&quot;fnref:6&quot; role=&quot;doc-noteref&quot;&gt;&lt;a href=&quot;#fn:6&quot; class=&quot;footnote&quot; rel=&quot;footnote&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;. This is being used by apps that are available in multiple app stores, to keep track on where they were downloaded from.&lt;/p&gt;

&lt;p&gt;Apparently, Google is also using this method to check if an app comes from &lt;em&gt;their&lt;/em&gt; app store, which should assure that they have verified and reviewed it. But what surprises me most, is that this mechanism can be fooled by just adding an extra parameter to the intent.&lt;/p&gt;

&lt;video autoplay=&quot;autoplay&quot; loop=&quot;loop&quot; class=&quot;full-img&quot;&gt;
  &lt;source src=&quot;/videos/opengarage.webm&quot; type=&quot;video/webm&quot; /&gt;
  &lt;source src=&quot;/videos/opengarage.mp4&quot; type=&quot;video/mp4&quot; /&gt;
&lt;/video&gt;
&lt;p&gt;&lt;small&gt;The Android Auto solution that I built by reverse engineering the official app.&lt;/small&gt;&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I think it is fun to have the ability to find out the inner working of everyday products, especially if you can benefit from these findings. I had expected that most of the time would go into reverse engineering the parking company app, but due to the simplicity of the app and the use of standard authentication, this was fairly easy.&lt;/p&gt;

&lt;p&gt;Most time went into setting up an Android Auto development environment and getting the hello-world app to compile after struggling with different Gradle and SDK versions. The restrictions with Android Auto required research, but the actual solution could not be easier.&lt;/p&gt;

&lt;p&gt;All in all, I am happy that it is working now, and it actually makes my life easier.&lt;/p&gt;

&lt;div class=&quot;footnotes&quot; role=&quot;doc-endnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://programmingwithstyle.com/posts/howihackedmycarguidescreatingcustomfirmware/&quot;&gt;https://programmingwithstyle.com/posts/howihackedmycarguidescreatingcustomfirmware/&lt;/a&gt; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:2&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/29353302/can-android-auto-apps-be-tested-on-actual-devices&quot;&gt;https://stackoverflow.com/questions/29353302/can-android-auto-apps-be-tested-on-actual-devices&lt;/a&gt; &lt;a href=&quot;#fnref:2&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:3&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://forum.xda-developers.com/f/android-auto-general.3834/&quot;&gt;https://forum.xda-developers.com/f/android-auto-general.3834/&lt;/a&gt; &lt;a href=&quot;#fnref:3&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:4&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://forum.xda-developers.com/t/fermata-media-player-audio-and-video-player-for-android-auto.4079519/&quot;&gt;https://forum.xda-developers.com/t/fermata-media-player-audio-and-video-player-for-android-auto.4079519/&lt;/a&gt; &lt;a href=&quot;#fnref:4&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:5&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.demo2s.com/android/android-intent-extra-not-unknown-source.html&quot;&gt;https://www.demo2s.com/android/android-intent-extra-not-unknown-source.html&lt;/a&gt; &lt;a href=&quot;#fnref:5&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id=&quot;fn:6&quot; role=&quot;doc-endnote&quot;&gt;
      &lt;p&gt;&lt;a href=&quot;https://www.yellowduck.be/posts/checking-if-android-app-installed-google-play&quot;&gt;https://www.yellowduck.be/posts/checking-if-android-app-installed-google-play&lt;/a&gt; &lt;a href=&quot;#fnref:6&quot; class=&quot;reversefootnote&quot; role=&quot;doc-backlink&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;
</description>
        <pubDate>Thu, 13 Oct 2022 00:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//tech/2022/10/13/reverse-engineering-parking-app</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//tech/2022/10/13/reverse-engineering-parking-app</guid>
        
        
        <category>tech</category>
        
      </item>
    
      <item>
        <title>Understanding the Shifting Stockbroker Market: Exploring No-Fee Trading and the Impact on Investors</title>
        <description>&lt;p&gt;The market of stockbrokers has been shifting since a couple of years. Several newcomers are offering so-called no-fee trading: free stock trading on designated exchanges or particular stocks. What is driving these new business models? &lt;!--more--&gt;&lt;/p&gt;

&lt;h3 id=&quot;a-brief-introduction-into-exchanges&quot;&gt;A brief introduction into exchanges&lt;/h3&gt;
&lt;p&gt;Stockbrokers are executing orders to buy and sell stock for their clients on an exchange. Traditionally, their business model is based on fees that are paid for every order that is being executed successfully. For example, buying 200 shares of Shell might cost you 6 euros in fees.&lt;/p&gt;

&lt;p&gt;However, not all exchanges are created equal. Sending the same order to multiple exchanges might result in different prices. This has to do with the fact that exchanges are matching buyers and sellers on the exchange itself, not on the market as whole.&lt;/p&gt;

&lt;h3 id=&quot;market-makers&quot;&gt;Market makers&lt;/h3&gt;

&lt;p&gt;The matching of buyers and sellers isn’t really about matching two individuals. This would make the stock market illiquid, as you need to wait till someone else is willing to do the opposite trade. For example, you would have to wait for some other party who is willing to sell at least 200 shares of Shell.&lt;/p&gt;

&lt;p&gt;Instead of trading with another individual, you are mostly trading with a market maker. A market maker is a party that has both a permanent buy and sell order with a large quantity open on an exchange. There is a 
small difference between the buy and sell prices that are being quoted, which is known as the spread. If an individual trader sends an order to the exchange, there is a big chance that it is being fulfilled by the market maker. The spread enables the market maker to make money, because it is continuously selling the stock at a slightly higher price than it is buying it.&lt;/p&gt;

&lt;h3 id=&quot;payment-for-order-flow&quot;&gt;Payment for order flow&lt;/h3&gt;
&lt;p&gt;As you can imagine, it really matters on which exchange your order is being executed. Different exchanges might have different agreements with market markers or act as a market maker themselves.&lt;/p&gt;

&lt;p&gt;For an exchange that also acts as a market maker, the execution of orders are profitable in itself due to the difference in buy and sell prices. This has evolved in such a way that exchanges are compensating stockbrokers that are routing the orders to their exchange. This phenomenon is called payment for order flow, or PFOF for short.&lt;/p&gt;

&lt;p&gt;In the Netherlands, a stockbroker is obliged to always act in the favor of the client. This makes it illegal to route orders to other, more expensive exchanges. However, in Germany, brokers are regulated under the &lt;em&gt;Bundesanstalt für Finanzdienstleistungsaufsicht&lt;/em&gt;. Which does not have this condition.&lt;/p&gt;

&lt;p&gt;Now Flatex has acquired DeGiro, basically all De Giro customers are not protected by Dutch regulation anymore, which also allows them to route orders to less favorable exchanges.&lt;/p&gt;

&lt;p&gt;In practice, you are free to choose the exchange that is being used, but you can see that they are &lt;a href=&quot;https://www.reddit.com/r/DutchFIRE/comments/smiu09/comment/hvx5oxh/&quot;&gt;pushing towards certain exchanges&lt;/a&gt;. Moreover, they are promoting trading outside the regular trading hours, which is only possible at their preferred exchange.&lt;/p&gt;

&lt;h3 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;All in all, I think it is important to know how a stock trade comes into being, as I am not a fan of obscure business models. A retail investor that is buying some shares with a limit price is probably not that much affected by this structure. However, with low volume products, such as options and high quantities, it might cost you serious money.&lt;/p&gt;

</description>
        <pubDate>Fri, 18 Feb 2022 12:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//finance/2022/02/18/are-you-the-product-in-modern-stocktrading</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//finance/2022/02/18/are-you-the-product-in-modern-stocktrading</guid>
        
        
        <category>finance</category>
        
      </item>
    
      <item>
        <title>Transforming broken Kindle into an E Ink Photo Frame with Synology Photos Integration</title>
        <description>&lt;p&gt;A couple of months ago, I accidentally stepped on my Kindle Voyage E-reader and cracked the screen on the edge. The E ink display itself was working fine, but the touchscreen stopped functioning, which made it impossible to control. What can we do with such a device before adding it to the pile of E-waste? &lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20220214_151832.jpg&quot; alt=&quot;Repurpose a broken Kindle as a photo frame, showing a picture of the village Spakenburg.&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20220214_151832.jpg 895w,    /assets/responsive-images/1080/20220214_151832.jpg 1080w,    /assets/responsive-images/1440/20220214_151832.jpg 1440w,    /assets/responsive-images/1790/20220214_151832.jpg 1790w,    /assets/responsive-images/2685/20220214_151832.jpg 2685w,    /assets/responsive-images/3580/20220214_151832.jpg 3580w, /./images/photos/20220214_151832.jpg 4032w&quot; /&gt;
&lt;small&gt;Repurpose a broken Kindle as a photo frame, showing a picture of the village Spakenburg.&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;jailbreak&quot;&gt;Jailbreak&lt;/h3&gt;
&lt;p&gt;Fortunately, there is a &lt;a href=&quot;https://www.mobileread.com/forums/forumdisplay.php?f=150&quot;&gt;jailbreak community&lt;/a&gt; around Amazon Kindle devices which allows you to run any type of arbitrary software. This enables us for example to play chess on a Kindle or add EPUB support. Jailbreaks are currently only possible if you are using an older, vulnerable version of the Kindle operating system. As I had never connected my Kindle to Wi-Fi (it is a book, why should it be connected?), it was still running a version that was possible to jailbreak. So on a spare evening, I connected the digitizer of another working Kindle to the broken one, jailbroke it and connected it to my Wi-Fi. This enabled me to SSH into the broken Kindle and interact with it again!&lt;/p&gt;

&lt;p&gt;So far, so good. Owning a nice low power device with high resolution E ink display that runs any software. Some projects for jailbroken Kindles are very interesting, such as repurposing a Kindle as a dashboard that shows the weather report and the latest news. However, as I would wish to have fewer distractions in my life, I thought it would be really cool to use it as a digital photo frame. Stumbled upon &lt;a href=&quot;https://github.com/pascalw/kindle-dash&quot;&gt;this project&lt;/a&gt; that loads a PNG from an external server and shows it on the display on predefined intervals.&lt;/p&gt;

&lt;h3 id=&quot;fetching-synology-photos&quot;&gt;Fetching Synology Photos&lt;/h3&gt;
&lt;p&gt;Just showing photos on a Kindle is not that user-friendly, as the images need to be processed, uploaded and opened manually. Since I am already storing all my photos on a Synology NAS, I wanted it to be a set-and-forget solution and automatically pick photos from a designated album.&lt;/p&gt;

&lt;p&gt;I created an album especially for this project and shared it publically with a link. Then I wrote a &lt;a href=&quot;https://github.com/landgenoot/kindle-synology-photos-photoframe/blob/main/src/refresh.sh&quot;&gt;shell script&lt;/a&gt; that parses the internal API from Synology Photos and downloads a random image from that particular album. This image is processed on the device, converted to grayscale with dithering using the &lt;code&gt;convert&lt;/code&gt; binary and rendered on the display. A simple cache makes sure that images that already have been displayed, are not downloaded and processed again.&lt;/p&gt;

&lt;h3 id=&quot;battery-life&quot;&gt;Battery life&lt;/h3&gt;
&lt;p&gt;What I really like about &lt;a href=&quot;https://github.com/pascalw/kindle-dash&quot;&gt;pascalw’s implementation&lt;/a&gt; is that it is suspending the device to RAM and using the &lt;a href=&quot;https://en.wikipedia.org/wiki/Real-time_clock_alarm&quot;&gt;Real Time Clock Alarm&lt;/a&gt; to wake it on a predefined moment. Therefore, it is able to get to sleep and disconnect from the Wi-Fi completely, which should keep it running for eight weeks on a single charge, according to Amazon.&lt;/p&gt;

&lt;p&gt;Now that I have been using it for a couple of months, I can say that by updating the picture every morning at 6 AM, the battery life seems to last over a month easily.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I was really surprised to see what such an old (2014) and low power device is capable of doing, even the &lt;code&gt;wget&lt;/code&gt; library seems up-to-date with the latest SSL standards. When I started this project, I expected to do all the processing on an external server in order to work around the limiting capabilities of the Kindle. I planned to write some Python to retrieve the image and parse the API from Synology, but I managed to do all that was needed in pure Bash.&lt;/p&gt;

&lt;p&gt;Secondly, I am surprised by the power efficiency of these devices. Keeping it in standby and connecting it to the Wi-Fi once in a while would drain the battery much quicker. Due to the possibility of suspending it to RAM combined with the RTC wake is perfect. I can even refresh the picture manually by pressing the power button, which generates an interrupt, wakes the devices, fetches a new photo and puts it back to sleep again!&lt;/p&gt;

&lt;p&gt;The image quality, however, is mediocre. It really depends on the image. In my experience, images with high contrast and non-detailed scenes are best suited for E ink displays. As I am manually selecting images for the photo frame, I am also taking this into account. This also accounts for the orientation, so that it is only showing photos that are taken in landscape.&lt;/p&gt;

&lt;div class=&quot;center&quot;&gt;
  &lt;img src=&quot;/images/refresh.gif&quot; /&gt;
  &lt;small&gt;Refresh of the photo, which happens every morning at 6 AM.&lt;/small&gt;
&lt;/div&gt;

&lt;p&gt;All in all, I think it is a really nice use case for of a broken Amazon Kindle, that would be worthless otherwise. Waking up with the surprise of a forgotten photo from a holiday two years ago is much more fun than an old-fashioned printed photo that never amazes you again.&lt;/p&gt;

&lt;h3 id=&quot;part-list&quot;&gt;Part list&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Part&lt;/th&gt;
      &lt;th style=&quot;text-align: right&quot;&gt;Price&lt;/th&gt;
      &lt;th&gt;Origin&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Jailbreakable Kindle&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;€35,-&lt;/td&gt;
      &lt;td&gt;Ebay Kleinanzeigen&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Mat&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;€10,-&lt;/td&gt;
      &lt;td&gt;At my local picture frame shop&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Photo frame&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;€3,-&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://jysk.nl/woonaccessoires/decoratie/fotolijsten/fotolijst-valter-13x18cm-zwart&quot;&gt;Jysk&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;90-degrees micro-USB connector&lt;/td&gt;
      &lt;td style=&quot;text-align: right&quot;&gt;€3,-&lt;/td&gt;
      &lt;td&gt;&lt;a href=&quot;https://nl.aliexpress.com/item/1005002487994454.html?gatewayAdapt=glo2nld&amp;amp;spm=a2g0o.9042311.0.0.3cd14c4dKxoad9&quot;&gt;AliExpress&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The code can be found at &lt;a href=&quot;https://github.com/landgenoot/kindle-synology-photos-photoframe&quot;&gt;github.com/landgenoot/kindle-synology-photos-photoframe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20220211_105719.jpg&quot; alt=&quot;Construction adhesive is used to glue it all together. Could look nicer, but I am lacking a workspace and proper tools at the moment.&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20220211_105719.jpg 895w,    /assets/responsive-images/1080/20220211_105719.jpg 1080w,    /assets/responsive-images/1440/20220211_105719.jpg 1440w,    /assets/responsive-images/1790/20220211_105719.jpg 1790w,    /assets/responsive-images/2685/20220211_105719.jpg 2685w,    /assets/responsive-images/3580/20220211_105719.jpg 3580w, /./images/photos/20220211_105719.jpg 4032w&quot; /&gt;
&lt;small&gt;Construction adhesive is used to glue it all together. Could look nicer, but I am lacking a workspace and proper tools at the moment.&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img loading=&quot;lazy&quot; class=&quot;full-img&quot; src=&quot;/assets/responsive-images/895/20220211_105730.jpg&quot; alt=&quot;The 90-degrees connector from AliExpress to charge it without taking it out of the frame.&quot; width=&quot;895&quot; height=&quot;692&quot; sizes=&quot;(max-width: 500px) 500px, 895px&quot; srcset=&quot;    /assets/responsive-images/895/20220211_105730.jpg 895w,    /assets/responsive-images/1080/20220211_105730.jpg 1080w,    /assets/responsive-images/1440/20220211_105730.jpg 1440w,    /assets/responsive-images/1790/20220211_105730.jpg 1790w,    /assets/responsive-images/2685/20220211_105730.jpg 2685w,    /assets/responsive-images/3580/20220211_105730.jpg 3580w, /./images/photos/20220211_105730.jpg 4032w&quot; /&gt;
&lt;small&gt;The 90-degrees connector from AliExpress to charge it without taking it out of the frame.&lt;/small&gt;
&lt;br /&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Feb 2022 12:00:00 +0000</pubDate>
        <link>https://daanmiddendorp.com//tech/2022/02/14/new-destination-for-my-broken-kindle</link>
        <guid isPermaLink="true">https://daanmiddendorp.com//tech/2022/02/14/new-destination-for-my-broken-kindle</guid>
        
        
        <category>tech</category>
        
      </item>
    
  </channel>
</rss>
