<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[CSDEV.IT]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>https://csdev.it/</link><image><url>https://csdev.it/favicon.png</url><title>CSDEV.IT</title><link>https://csdev.it/</link></image><generator>Ghost 3.33</generator><lastBuildDate>Sat, 09 May 2026 16:14:48 GMT</lastBuildDate><atom:link href="https://csdev.it/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Migration to Uberspace 7 done]]></title><description><![CDATA[<p>Even if I was not posting something in the recent years I kept the blog alive as it my articles about the build traffic light, etc have been mentioned / linked on some other sides or podcasts.</p><p>This blog is hosted on an <a href="https://uberspace.de">uberspace</a>. It was on U6 the last years</p>]]></description><link>https://csdev.it/migration-to-uberspace-7-done/</link><guid isPermaLink="false">5f6902b97371470e67a89d2a</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Mon, 21 Sep 2020 20:02:34 GMT</pubDate><content:encoded><![CDATA[<p>Even if I was not posting something in the recent years I kept the blog alive as it my articles about the build traffic light, etc have been mentioned / linked on some other sides or podcasts.</p><p>This blog is hosted on an <a href="https://uberspace.de">uberspace</a>. It was on U6 the last years and I didn't touch it - Straight to the rule "Never touch a running system :-)</p><p>All U6 spaces will be shut down by end of 2020 in favor of the new U7 ones. So some work had to be done to keep the blog alive. The admins of uberspace wrote a migration script to support us users as much as possible. But nevertheless for my blog it still required some work as I didn't touch it for so long.</p><p>What was necessary to migrate this blog from U6 to U7?</p><ul><li>Kick off the migration script that copies all data, databases, eMail-Accounts and so to the new U7</li><li>Clean up things not needed any more (databases, files, scripts)</li><li>Export Blogposts, update Blog to Ghost version 1.xx, import posts, export them again, update to Ghost version 3.xx, import again. Some background: As I was not updating Ghost the last years I was still on version 0.11 that did not allow direct updates to version 3.xx - so the step to intermediate version 1.xx was necessary. There is a guide for Ghost on U7 I can recommend you: <a href="https://lab.uberspace.de/guide_ghost.html">https://lab.uberspace.de/guide_ghost.html</a></li><li>disable old cron-jobs that did the lets-encrypt https-certificate renewal, which comes out of the box with U7</li><li>Update all DNS-entries to use my custom domain with U7 (new A, AAAA, MX-records)</li><li>reconfigure all eMail settings in my eMail-clients</li></ul><p>That was basically it. It took me roughly 1 day. After doing it once with this site as a dry-run I can continue to migrate my other uberspaces now :-)</p>]]></content:encoded></item><item><title><![CDATA["Alexa, start skill development"]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Currently I hear / read everywhere <em>&quot;Voice Interaction is the future&quot;</em>. I'm not totally convinced so far. But I'm pretty sure that is a market for apps made for voice interaction.<br>
In this post I want to write about the challenges I faced developing my first own app for</p>]]></description><link>https://csdev.it/alexa-start-skill-development/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f12</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Mon, 11 Sep 2017 17:31:44 GMT</pubDate><media:content url="https://csdev.it/content/images/2017/09/Screen-Shot-2017-09-11-at-12.01.52.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://csdev.it/content/images/2017/09/Screen-Shot-2017-09-11-at-12.01.52.png" alt=""Alexa, start skill development""><p>Currently I hear / read everywhere <em>&quot;Voice Interaction is the future&quot;</em>. I'm not totally convinced so far. But I'm pretty sure that is a market for apps made for voice interaction.<br>
In this post I want to write about the challenges I faced developing my first own app for voice interaction.</p>
<blockquote>
<p><span style="color:orange"><strong>If you are located in Germany feel free to test my skill &quot;BilloBenzin&quot; for free. Feedback is very welcome.</strong><br>
To get it click the following link:</span><br>
<a href="https://www.amazon.de/dp/B0757Z6W9S/ref=sr_1_1?ie=UTF8&amp;qid=1505149929&amp;sr=8-1&amp;keywords=billobenzin">&gt; BilloBenzin @ Amazon.de &lt;</a></p>
</blockquote>
<p>I was curious how hard it is to develop an own skill (application for voice in the amazon-universe). After attending a full-day workshop with <a href="https://twitter.com/muttonia">@muttonia</a> I got a very good overview what needs to be done to develop / publish an own skill.<br>
Especially for the german market it is attractive to develop skills, because there are not that many skills in the store so far (I think @muttonia mentioned roughtly 2.000 compared to over 1 million in the US).</p>
<p>I started to groom some ideas to develop my first own skill and decided to go with the usecase of cheap petrol. The goal was to develop a skill that should tell you the cheapest petrol station in your area.<br>
To keep the scope small for my first development I only want to target areas within Germany (only released for the german skill-store). Furthermore I wanted to limit the interaction to a minimum but still useful - that means after the user gets the answer the skill is stopped (no real conversations, which would be a tricky topic at the moment anyways).</p>
<p>Below I will go through the things I learned and the challenges I had to face.</p>
<h4 id="conceptbehindalexaonechoechodot">Concept behind Alexa on Echo, Echo Dot,...</h4>
<p>An Alexa-enabled device - I think that's how Amazon calls it - like the Echo or Echo Dot just acts as a bridge to cloud-functions. It permanently listens for a keyword like <em>&quot;Echo&quot;, &quot;Alexa&quot; or &quot;Computer&quot;</em> followed by a command, the skill-invocation name and optionally a phrase containing some varible inputs (there is also an &quot;inversion&quot; of the sentence structure that works, see the invocation picture below).<br>
Everything after the keyword &quot;Alexa&quot; is basically the intent, which is transformed via speech-to-text and send as a JSON file to the cloud . There it is processed by an AWS-Lambda-Function (or an alternative cloud-function). The result is returned back as a JSON to the Alexa-enabled device where a text-to-speech transformation is applied. The result is vocalized to the user.</p>
<h4 id="invocationnameandinteractionmodel">Invocation-name and interaction model</h4>
<p><img src="https://csdev.it/content/images/2017/09/IMG_20170828_144522.jpg" alt=""Alexa, start skill development""><br>
To get the expected results you really need to care about the <strong>invocation-name</strong>, the <strong>syntax</strong> of your invocation sentences, the parameters (<strong>Intent-Slot-Types</strong>) and the <strong>error-handling</strong>.</p>
<h5 id="invocationname">invocation-name</h5>
<p>The invocation-name is very tricky, especially in the german language if you want to come up with a nice syntactical meaningful phrase. You can only define one invocation-name (does not need to be the same as your skillname) - so be careful here.<br>
During my development / review-process I had to change the invocation-name 2 times due to the following reasons:</p>
<ul>
<li>My first invocation-name was &quot;benzinpreis&quot; (means petrolprice) and I wanted to use it in combination with the command &quot;erfrage&quot; (means ask). That could give me some nice natural sounding german phrases like <em>&quot;Alexa, erfrage Benzinpreis&quot;</em> or <em>&quot;Alexa, erfrage Benzinpreis für Diesel in Frankfurt&quot;</em> - which would be pretty neat because the phrases are short and contain all the necessary inputs.<br>
This invocation-name was rejected in my first certification by Amazon because &quot;erfrage&quot; is not an allowed/official command for Alexa even if it is perfectly recognized all the times - most likely because it sounds similar to &quot;frage&quot; which is officially supported.</li>
<li>My second invocation-name was &quot;billobenz&quot; (just a catchy name). This one I had to change, because Alexa seems to have some problems with the german language. In most of the cases &quot;billobenz&quot; was understoud by Alexa as &quot;below bands&quot; and than it could not handle it / find a skill matching &quot;below bands&quot;.</li>
<li>I ended up with &quot;billobenzin&quot; (catchy name, means something like &quot;cheapypetrol). This one is perfectly recognized, but it makes meaningful invocation-phrases longer, e.g. <em>&quot;Alexa, frage BilloBenzin nach dem günstigsten Diesel Preis in Frankfurt&quot;</em>.</li>
</ul>
<h5 id="intentscheme">intent-scheme</h5>
<p>The intent-scheme is a JSON-File that defines the intents you (can) handle in your cloud-function and what parameters (so called Slots) they take as an input.<br>
Below you can see a definition of 2 intents - one custom and the standard HelpIntent. As you can see the custom intent defines 2 input-slots.<br>
In the intent-scheme you can define more intents than you currently resolve / handle in your cloud-function. This allows you to adjust the cloud-function while your skill is live without a new review process. I would not recommend to do this, because if you do not predefine sample utterances for your unimplemented intents they will most likely not be recognized. If you add sample utterances for unimplemented intents you will get problems if the user starts such an intent, because you do not handle it.<br>
If you really want to go with that I highly recommend to at least provide a stub implementation in your cloud-function that tells the user that this intent will be handled / implemented later and route her to the help-intent. <strong>But: This is not a good UX!</strong></p>
<pre><code class="language-language-json">{
  &quot;intents&quot;: [
    {
      &quot;slots&quot;: [
        {
          &quot;name&quot;: &quot;city&quot;,
          &quot;type&quot;: &quot;AMAZON.DE_CITY&quot;
        },
        {
          &quot;name&quot;: &quot;petrolType&quot;,
          &quot;type&quot;: &quot;PETROL_TYPE&quot;
        }
      ],
      &quot;intent&quot;: &quot;GetCheapestPetrolForCityWithPetrolTypeIntent&quot;
    },
    {
      &quot;intent&quot;: &quot;AMAZON.HelpIntent&quot;
    }
  ]
}
</code></pre>
<h5 id="slottypes">slot-types</h5>
<p>Slot-Types define the input-&quot;words&quot; that should be recognised for an intent. You have to give your input a type / a list of values that Alexa knows / recognises. In the US you can use Literal-Type too, which is <strong>any</strong> input with the consequence that you need to provide a lot more sample utterances to make it close to deterministic. For german skills Literal-Type is not supported.<br>
In the JSON-codesnipped above you see two of my slots for a custom-intent. <em>petrolType</em> has a custom slot-type. <em>city</em> uses a predefined type &quot;AMAZON.DE CITY&quot; which I extended. It contains basically a list with 5.000 german city-names. It was a challenge for me to find the right type for city, because first I wanted to use something like a Literal for free input, because the backend that resolves the area also supports streets, zip-codes, e.g. I wanted to handle any address input all at once. I had to change my way of working / thinking here and needed to be more explicit. So I decided to use the predefined type &quot;AMAZON.DE_CITY&quot; which covers about 5.000 cities. Unfortunately I had to find out that not all Cities I tested are covered. E.g. &quot;Nossen&quot; (the town where I lived the first years of my life) is not recognised. So I had to extend the type. Unfortunately there is an uncertainty that I did not add a city a customer will ask for. That is a drawback of this type.</p>
<h5 id="syntax">syntax</h5>
<p>You should support the machine-learning algorithms of Amazon with a lot of Sample-Utterances how to invoke your skill - there you also define which element of the phrase is a parameter / slot you want to handle in your cloud-function (see examples of my skill in picture below).<br>
<img src="https://csdev.it/content/images/2017/09/Screen-Shot-2017-09-11-at-13.37.55.png" alt=""Alexa, start skill development""></p>
<p>In the Alexa workshop it was recommended to use at least 40 samples. The more you provide the better the intention of the user is recognised.</p>
<h4 id="aws">AWS</h4>
<p>I know the concepts of serverless-computing and lambda-functions in the cloud, but I never had the chance to work with them before.<br>
Amazon offers developers everything you can think of as a cloud-based service that you paid only on a usage / time / request base. For Alexa-skills the integration is made very easy for you because Amazon already gives you Alexa presets for a quick start. It is highly recommended to use <a href="https://eu-west-1.console.aws.amazon.com/">AWS</a>.<br>
My skill uses the following AWS-Components: A Lambda function based on the <em>alexa-skill-kit-sdk-factskill</em> written in Node.js / Javascript, a DynamoDB and S3 for Skill-Graphics. Using all these components from Amazon makes it easy and fast to develop your skill. But it comes with the risk of a vendor-lock-in.<br>
I would highly recommend to use a lambda function based on the <em>alexa-skill-kit-sdk-factskill</em> template (for the start) because it includes already the alexa-sdk, so you can directly start developing your intent-handlers.<br>
It is also quite handy to use a DynamoDB for persisting the state of your skill. In my skill e.g. I store the petrol-type and the city the user asked for. So in future requests for the cheapest price she can take the shortcut in just asking Alexa to open the skill and it will respond with the latest price for the remembered city and petrol.<br>
Your AWS-Lambda function has a unique identifier that can be directly connected to your skill in the <a href="https://developer.amazon.com/">Amazon Developer console (Alexa)</a> (see example in picture below).</p>
<p><img src="https://csdev.it/content/images/2017/09/Screen-Shot-2017-09-11-at-18.25.57.png" alt=""Alexa, start skill development""></p>
<h4 id="providecardsinyourskill">Provide Cards in your skill</h4>
<p>Amazon offers the functionality to put detailed / additional information on so called cards that appear in the Alexa-App (and maybe on the Echo show?). In my skill Alexa just responds with the one and only cheapest petrol-station in speech but I show the Top 3 with additional information in a card (see screenshot below).</p>
<p><img src="https://csdev.it/content/images/2017/09/card_small.png" alt=""Alexa, start skill development""></p>
<h4 id="unittestingaskill">Unit-Testing a skill</h4>
<p>Unfortunately I didn't try it so far. But it is definitely on my list because the bigger your skill gets the more tricky it gets to test it manually.<br>
As a start I recommend reading the following blog-post: <a href="https://medium.com/@jjbskir/unit-testing-an-amazon-alexa-skill-with-node-js-and-jasmine-98982544471f">Unit-Testing an Amazon Alexa Skill</a>.</p>
<h4 id="certificationreviewprocess">Certification / review process</h4>
<p>I didn't pass the certification of my skill two times. But most of the review comments really helped me to improve my skill and make it more robust.<br>
I recommend to read through the <a href="https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-voice-interface-and-user-experience-testing?ref_=pe_679090_102923190#43-intent-response-design">Submission Checklist</a> because it is pretty helpful.</p>
<h4 id="skillpropagation">Skill propagation</h4>
<p>That's something I also have to figure out. How to attract potential customers with your skill? Currently they only can search for specific keywords in the skill-store and will find several skills fulfilling the same usecase. I think you need a lot of unique users to get featured by Amazon. I hope to find this out during the lifetime of my skill. I will update this post accordingly.<br>
Any tips in this direction are highly welcomed.</p>
<h4 id="attractcustomersthroughbehaviornireyalshookmodel">Attract customers through behavior - Nir Eyal's Hook Model</h4>
<p><img src="https://csdev.it/content/images/2017/09/IMG_20170828_150237.jpg" alt=""Alexa, start skill development""></p>
<p>Nir Eyal is a Silicon Valley based product designer 👨‍🎨 who came up with the Hook Model / Habit-forming products in his bestseller book <a href="https://www.amazon.com/Hooked-How-Build-Habit-Forming-Products/dp/1591847788/ref=sr_1_1?ie=UTF8&amp;qid=1505127743&amp;sr=8-1&amp;keywords=Hooked%3A+How+To+Build+Habit-forming+Products">Hooked: How to Build Habit-Forming Products</a>.<br>
I just want to go through the 4 aspects shown in the picture above in quick to describe how my skill (not) addresses them.</p>
<ul>
<li><strong>Trigger</strong> The actual trigger that leads the user to use the skill. An external trigger could e.g. be that the user has seen the Skill-Icon and the good reviews in the store and wants to try it out herself. After the first use she repeats to use the skill (internal trigger).</li>
<li><strong>Action</strong> The user should be able to interact with ease and according to human behaviour. In the case of my skill this would be short invocation sentences in a natural, familiar german syntax.</li>
<li><strong>Variable Reward</strong> The skill should vary its responses to sound more natural. You could e.g. define several answer-templates and choose one randomly. This motivates the user to keep on using the skill and get to hear the other answers. This variation differentiates Nir Eyal's Model from traditional feedback loops. I currently do not vary the answers in my skill (besides the actual price-infos) but will encourage this in one of the next updates.</li>
<li><strong>Investment</strong> The more the user invests into the product (money, time, information) the more she values it. For my skill the user has not that much information or money she needs to invest. The only investment is the time she uses the skill. And maybe the precision of the inputs to get more tailored answers.<br>
In complex skills like role-playing games the user can build an inventory and gets more and more knowledge of the game. She invests time to bring the game to an end and that's an investment.</li>
</ul>
<p>This was just a quick outtake. I highly recommend to read the book of Nir Eyal. Your future app-developments will profit from it 😉</p>
<h4 id="usefullinks">Useful Links</h4>
<ul>
<li><a href="https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs#adding-multi-language-support-for-skill">Alexa Node Skill SDK on Github</a> as a reference how to implement things</li>
<li><a href="https://console.aws.amazon.com/">AWS Console</a> for cloud-functions</li>
<li><a href="https://developer.amazon.com/">Amazon Developer Console</a> to create and test your actual skills</li>
<li><a href="https://echosim.io/">Echosim.io</a> - simulates an Echo in to test your skill with voice for the times you have no real echo in reach (seems to work only in Firefox)</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Blog-Updates]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Hi,</p>
<p>I want to revitalize my blogging-efforts and thought about moving everything to <a href="https://medium.com">medium.com</a> because it offers you a huge reachability / big community. On the other hand you give everything in the hands of their platform. I read some blog-post about moving to medium and coming back to a</p>]]></description><link>https://csdev.it/blog-updates/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f11</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Mon, 11 Sep 2017 09:56:08 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Hi,</p>
<p>I want to revitalize my blogging-efforts and thought about moving everything to <a href="https://medium.com">medium.com</a> because it offers you a huge reachability / big community. On the other hand you give everything in the hands of their platform. I read some blog-post about moving to medium and coming back to a personal blog - I decided to not hurry moving everything to medium and stick to my personal small page here, because I write these posts mainly for myself - straight according the KISS-principle.</p>
<p>Nevertheless there have been some changes:</p>
<ul>
<li>I made all the latest updates to my ghost installation</li>
<li>Switched to HTTPS via <a href="https://letsencrypt.org">let's encrypt</a> - they give you free (trustworthy) certificates valid for 90 days. I configured a cronjob to renew the certs every month.</li>
<li>Changed the theme to the most minimalistic one i found that attracted me - <a href="https://github.com/slunsford/arabica">&quot;arabica&quot; on github</a>. I just extended it by adding Prism.js for Syntax-highlighting.</li>
</ul>
<p>I already started with this post to write my articles in english to make them easy accessible for a more international audience.<br>
Future posts I will most likely spread on some platforms like Linked-In and Twitter where I have some english speaking followers.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Android IOT - Einstieg]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Mit dem Release der Developer Preview von Android IOT bringt Google Android auf Embedded Devices. Insbesondere Android-Entwicklern soll so die IOT-Welt zugänglicher gemacht werden, da die generelle Programmstruktur bzw. der Application-Lifecycle dem einer Android-App sehr ähnlich sind.</p>
<p>Vorerst werden lediglich Intel Edison, Intel Joule, NXP Pico und Raspberry Pi 3</p>]]></description><link>https://csdev.it/post-post/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f10</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Sat, 18 Mar 2017 14:47:59 GMT</pubDate><media:content url="https://csdev.it/content/images/2017/03/raspi.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://csdev.it/content/images/2017/03/raspi.jpg" alt="Android IOT - Einstieg"><p>Mit dem Release der Developer Preview von Android IOT bringt Google Android auf Embedded Devices. Insbesondere Android-Entwicklern soll so die IOT-Welt zugänglicher gemacht werden, da die generelle Programmstruktur bzw. der Application-Lifecycle dem einer Android-App sehr ähnlich sind.</p>
<p>Vorerst werden lediglich Intel Edison, Intel Joule, NXP Pico und Raspberry Pi 3 Boards unterstützt. Mein vorhandener Raspberry Pi 1 leider nicht, ich nehme an, dass die älteren RaspberryPi-Boards zu wenig RAM für Android haben und deshalb offiziell nicht unterstützt werden.<br>
Der Raspberry Pi 3 stellt den günstigsten Einstieg in Android IOT dar. Für den RasPi 3B, eine <a href="https://www.amazon.de/gp/product/B013CP5F90/ref=oh_aui_detailpage_o01_s00?ie=UTF8&amp;psc=1">SanDisk Extreme 16GB microSD-Card</a> und das  <a href="https://www.amazon.de/gp/product/B01CCPKCSK/ref=oh_aui_detailpage_o00_s00?ie=UTF8&amp;psc=1">offizielle Gehäuse</a> habe ich insgesamt knapp 58€ gezahlt. Ein Micro-USB-Netzteil war noch von meinem Raspberry Pi 1 vorhanden. Ebenso habe ich bereits früher ein Sunfounder Super Kit V2.0 gekauft welches einen Grundschatz an LEDs, Widerständen, Display, Motor, Breadboard ... bereitstellt. Dies ist sehr nützlich um mit IOT-Projekten jeglicher Art zu starten (Arduino, RaspberryPi, ...) wenn man sich nicht ausschließlich auf Konsolenausgaben limitieren möchte. Ein vergleichbares Kit kann man beispielsweise unter folgendem Link erwerben: <a href="https://www.amazon.de/Sunfounder-Project-Raspberry-Deutscher-Anleitung/dp/B019T0PXIU/ref=sr_1_1?ie=UTF8&amp;qid=1489840712&amp;sr=8-1&amp;keywords=sunfounder+super+kit++raspberry">Sunfounder Starter Kit</a>.</p>
<p>Die SanDisk Extreme Speicherkarte bietet sehr gute Transferraten und das offizielle Gehäuse ist sehr flexibel, da es Modular aufgebaut ist und Möglichkeiten hat die GPIO-Ports und Anschlüsse wahlweise zu bedecken oder zugänglich zu machen.</p>
<p>Zum Start mit Android IOT ist es empfehlenswert sich auf den offiziellen Google-Seiten einzulesen (<a href="https://developer.android.com/things/preview/index.html">https://developer.android.com/things/preview/index.html</a>). Google bietet auch einen Elektronik-Crashkurs / Basiswissen - falls man noch nie an Elektronik gebastelt hat oder sein Wissen auffrischen möchte, ist die folgende Page lesenswert: <a href="https://developer.android.com/things/hardware/hardware-101.html">https://developer.android.com/things/hardware/hardware-101.html</a>.</p>
<h2 id="bentigtesoftware">Benötigte Software:</h2>
<ul>
<li>ADB (Android Debugging Bridge) enthalten in den Android SDK Commandline Tools im Paket Platform-Tools. Download unter folgendem Link: <a href="https://developer.android.com/studio/index.html#downloads">https://developer.android.com/studio/index.html#downloads</a></li>
<li>Android IOT-SystemImage: <a href="https://developer.android.com/things/preview/download.html">https://developer.android.com/things/preview/download.html</a></li>
<li><em>(Empfehlenswert ist es zudem die AndroidStudio-Entwicklungsumgebung zu installieren: <a href="https://developer.android.com/studio/index.html#downloads">https://developer.android.com/studio/index.html#downloads</a>)</em></li>
</ul>
<h2 id="bootstrapping">Bootstrapping</h2>
<p><strong>Ich arbeite unter macOS, deshalb beziehen sich alle folgenden Konsolen-Codesnippets auf den Mac. Unter Windows muss man alternativ wahrscheinlich die adb.bat / oder adb.exe verwenden.</strong></p>
<p>Um die erste IOT-App auf den RaspberryPi zu deployen sind folgende Schritte notwendig:</p>
<ol>
<li>Android-IOT muss auf der MicroSD-Karte des RaspberryPi installiert werden.</li>
</ol>
<ul>
<li>Neueste Version vom Android IOT SystemImage downloaden: <a href="https://developer.android.com/things/preview/download.html">https://developer.android.com/things/preview/download.html</a></li>
<li>Image entpacken und auf die MicroSD-Karte installieren (unter dem folgenden Link findet man Anleitungen für Win, Linux und macOS: <a href="https://www.raspberrypi.org/documentation/installation/installing-images/">https://www.raspberrypi.org/documentation/installation/installing-images/</a>)</li>
</ul>
<ol start="2">
<li>MicroSD-Karte mit vorinstalliertem Image in RaspberryPi stecken, Display per HDMI und Netzwerk per LAN-Kabel anschließen.</li>
</ol>
<ul>
<li>Display wird initial benötigt, da nach dem Bootvorgang die IP des RaspberryPi im Display eingeblendet wird.</li>
<li>LAN-Verbindung brauchen brauchen wir initial um eine erste Internetverbindung bereitzustellen (IP per DHCP). Darüber kann das WIFI-Setup durchgeführt werden.</li>
</ul>
<ol start="3">
<li>AndroidIOT booten indem man den RaspberryPi per MicroUSB mit Strom  versorgt.</li>
</ol>
<ul>
<li>Nach erfolgreichen Boot wird unten im Display die IP des RaspberryPi angezeigt</li>
</ul>
<ol start="4">
<li>Testen ob man sich auf den RaspberryPi verbinden kann.</li>
</ol>
<pre><code class="language-language-bash">$ cd &lt;AndroidSdkPath&gt;/platform-tools
$ ./adb connect &lt;IP des RaspberryPi&gt;
</code></pre>
<ol start="5">
<li>Wifi installieren.</li>
</ol>
<pre><code class="language-language-bash">$ adb shell am startservice \
    -n com.google.wifisetup/.WifiSetupService \
    -a WifiSetupService.Connect \
    -e ssid &lt;WLAN-Name&gt; \
    -e passphrase &lt;WLAN-Passwort&gt;
</code></pre>
<ul>
<li>Nach einem Neustart wird auch die WLAN-IP im Display angezeigt und man kann das Netzwerkkabel entfernen und sich mittels ADB (adb connect) per WLAN mit dem RaspberryPi verbinden.</li>
</ul>
<h2 id="helloworld">Hello World</h2>
<p>Um zu schauen ob alles funktioniert, können wir eine erste kleine App erstellen, welche lediglich die verfügbaren GPIO-Ports in die Konsole postet.</p>
<ul>
<li>Neues Android Studio Projekt anlegen (File &gt; New &gt; New Project) mit folgenden Eckdaten:
<ul>
<li>App-Name: <strong>IotTest</strong></li>
<li>Target Android Devices: <strong>Phone and Tablet, Minimum SDK API 24</strong> (AndroidIOT ist noch nicht als Target aufgeführt, ist aber an der Stelle kein Problem, da Wir das Projekt später dahingehend anpassen werden)</li>
<li>Activity-Template: <strong>Empty Activity</strong></li>
<li>Activity-Name: <strong>HomeActivity</strong></li>
<li>IOT-Apps sind sehr ähnlich zu den normalen Android-Apps. Aus diesem Grund können wir auch das &quot;Phone and Tablet&quot; Template nehmen.</li>
</ul>
</li>
<li>Wir müssen unsere App mitteilen, dass sie die IOT-Systemlibrary nutzen soll, dazu müssen wir die <strong>dependencies</strong>-Section der Build.gradle des <strong>app</strong>-Projekts um folgende Zeile Code ergänzen:<br>
<code>provided 'com.google.android.things:androidthings:0.1-devpreview'</code></li>
<li>Des Weiteren müssen wir in der <strong>AndroidManifest.xml</strong> ergänzen, dass die IOT-Library genutzt wird (<code>&lt;uses-library android:name=&quot;com.google.android.things&quot;/&gt;</code>) und mindestens einen Intent-Filter hinzufügen, damit das System unsere App nach dem Booten startet.</li>
</ul>
<pre><code class="language-language-xml">          &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot;/&gt;
                &lt;category android:name=&quot;android.intent.category.IOT_LAUNCHER&quot;/&gt;
                &lt;category android:name=&quot;android.intent.category.DEFAULT&quot;/&gt;
            &lt;/intent-filter&gt;
</code></pre>
<p>Wir werden einen weiteren Intent-Filter setzen, damit Android-Studio unsere <strong>HomeActivity</strong> beim Klick des Run-Buttons startet.</p>
<pre><code class="language-language-xml">            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot;/&gt;
                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot;/&gt;
            &lt;/intent-filter&gt;
</code></pre>
<p>Am Ende sieht meine <strong>AndroidManifest.xml</strong> wie folgt aus:</p>
<pre><code class="language-language-xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    package=&quot;csdev.it.iottest&quot;&gt;

    &lt;application
        android:allowBackup=&quot;true&quot;
        android:label=&quot;@string/app_name&quot;
        android:theme=&quot;@style/AppTheme&quot;&gt;
        &lt;uses-library android:name=&quot;com.google.android.things&quot;/&gt;

        &lt;activity android:name=&quot;.HomeActivity&quot;&gt;
            &lt;!-- Launch activity as default from Android Studio --&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot;/&gt;
                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot;/&gt;
            &lt;/intent-filter&gt;

            &lt;!-- Launch activity automatically on boot --&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot;/&gt;
                &lt;category android:name=&quot;android.intent.category.IOT_LAUNCHER&quot;/&gt;
                &lt;category android:name=&quot;android.intent.category.DEFAULT&quot;/&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;

    &lt;/application&gt;

&lt;/manifest&gt;
</code></pre>
<p>Da wir kein UI verwenden können wir einige überflüssige Sachen die mit dem App-Template reinkamen aus dem Manifest löschen, wie z.B.:</p>
<ul>
<li><code>android:icon=&quot;@mipmap/ic_launcher&quot;</code></li>
<li><code>android:roundIcon=&quot;@mipmap/ic_launcher_round&quot;</code></li>
<li><code>android:supportsRtl=&quot;true&quot;</code><br>
<strong>Wichtig an dieser Stelle ist, dass <code>android:theme=&quot;@style/AppTheme&quot;</code>enthalten bleibt, da die App sonst nicht startet.</strong></li>
</ul>
<p>In den Resource-Files des Projekts (<code>res</code>) kann man ebenfalls alle Layouts (aktuell nur eins), sowie alles unter mipmap (die Icons) löschen, da wir keine UI verwenden.</p>
<ul>
<li>Als letztes muss noch unsere <strong>HomeActivity</strong> angepasst werden. In der <code>onCreate()</code> Methode geben wir unser <code>Hallo World</code> aus und lassen uns vom <code>PeripheralManagerService</code> alle  verfügbaren GPIO-Ports auflisten.<br>
Meine <strong>HomeActivity</strong> sieht wie folgt aus:</li>
</ul>
<pre><code class="language-language-java">package csdev.it.iottest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.things.pio.PeripheralManagerService;

public class HomeActivity extends AppCompatActivity {

    private static final String TAG = &quot;HomeActivity&quot;;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d(TAG, &quot;Hello World&quot;);

        PeripheralManagerService service = new PeripheralManagerService();
        Log.d(TAG, &quot;Available GPIO: &quot; + service.getGpioList());
    }
}
</code></pre>
<p>Auch hier kann man <code>setContentView(R.layout.activity_main);</code> löschen, da wir kein XML-Layout nutzen.<br>
Vielleicht kommt in einer der nächsten Android-Studio-Versionen ein &quot;bereinigtes&quot; IOT-Template von Google hinzu.</p>
<ul>
<li>Um die App auszuprobieren müssen wir uns zunächst per ADB mittels WLAN/LAN mit dem RaspberryPi verbinden, dazu kann man am einfachsten die in Android-Studio mitgelieferte Konsole nutzen oder alternativ ein Terminal aufmachen:</li>
</ul>
<pre><code class="language-language-bash">$ ./adb connect &lt;IP des RaspberryPi&gt;
</code></pre>
<ul>
<li>Eine erfolgreiche Verbindung zum RaspberryPi wird mit folgender Ausgabe quittiert:</li>
</ul>
<pre><code class="language-language-bash">* daemon not running. starting it now at tcp:5037 *
* daemon started successfully *
connected to &lt;IP des RaspberryPi:Port&gt;
</code></pre>
<ul>
<li>Nachdem die Verbindung hergestellt ist, können wir unsere HelloWorld-App mit Android-Studio auf dem RaspberryPi deployen. Dazu einfach den grünen Run-Button drücken und anschließend den RaspberryPi (z.B. &quot;unknown Iot_rpi3 (Android 7.0, API24) in der Deployment-Target-Liste auswählen und den &quot;OK&quot;-Button drücken. Daraufhin wird die App gebaut und auf dem RaspberryPi installiert sowie die HomeActivity gestartet.<br>
Über Android-Studio (Android Monitor &gt; logcat)können wir die Konsolenausgabe des RaspberryPi aufrufen und schauen ob unser HelloWorld ausgegeben wird (alternativ per Terminal <code>$ ./adb logcat</code>). In den Logs sollten 2 Zeilen ähnlich den folgenden zu finden sein:</li>
</ul>
<pre><code class="language-language-bash">03-18 14:19:02.048  1754  1754 D HomeActivity: Hello World
03-18 14:19:02.055  1754  1754 D HomeActivity: Available GPIO: [BCM12, BCM13, BCM16, BCM17, BCM18, BCM19, BCM20, BCM21, BCM22, BCM23, BCM24, BCM25, BCM26, BCM27, BCM4, BCM5, BCM6]
</code></pre>
<p>Mit diesem HelloWorld-Beispiel schafft ihr den ersten Durchstich um Apps auf AndroidIOT zu deployen. Wesentlich spannender ist die Interaktion der IOT-Apps mit externen Hardwarekomponenten, auf welche ich hoffentlich in künftigen Blogposts eingehen kann.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[Build-Ampel] 4 Die Software]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Im <a href="http://csdev.it/build-ampel-3-der-finale-zusammenbau/">letzten Abschnitt</a> habe ich den Zusammenbau beschrieben.<br>
Hier soll es nun kurz um die softwareseitige Ansteuerung der Ampel gehen.</p>
<p>Ich habe mich dazu entschieden den Arduino passiv anzusteuern. Dafür wurde per ArduinoIDE StandardFirmata auf den Arduino gespielt, wodurch er sich über USB seriell ansteuern lässt. Dies erleichtert einige Dinge</p>]]></description><link>https://csdev.it/cs85-me-com/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f0f</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Wed, 20 Jul 2016 20:38:30 GMT</pubDate><media:content url="https://csdev.it/content/images/2016/07/Bildschirmfoto-2016-07-19-um-16-15-07.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://csdev.it/content/images/2016/07/Bildschirmfoto-2016-07-19-um-16-15-07.png" alt="[Build-Ampel] 4 Die Software"><p>Im <a href="http://csdev.it/build-ampel-3-der-finale-zusammenbau/">letzten Abschnitt</a> habe ich den Zusammenbau beschrieben.<br>
Hier soll es nun kurz um die softwareseitige Ansteuerung der Ampel gehen.</p>
<p>Ich habe mich dazu entschieden den Arduino passiv anzusteuern. Dafür wurde per ArduinoIDE StandardFirmata auf den Arduino gespielt, wodurch er sich über USB seriell ansteuern lässt. Dies erleichtert einige Dinge und verlagert sämtliche Logik auf den PC an den die Ampel angeschlossen ist. Ein wesentlicher Vorteil ist, dass man auch komplexere Netzwerk-Settings (VPN/Proxy/etc) relativ easy umsetzen kann. Nachteil dieser Lösung ist sicherlich, dass man einen Rechner braucht, der sich um die Ansteuerung kümmert.<br>
In meinem Fall war es wichtiger den Arduino möglichst einfach in ein VPN zu bringen. Der Rechner ist sowieso vorhanden :-)</p>
<p>Die serielle Steuerung des Arduinos übernimmt in meinem fall ein kleines NodeJS-Script, welches den aktuellen Teamcity-Build-Status alle 15 Sekunden abfragt und die Ampel-Lampen per Arduino entsprechend &quot;grün&quot; (letzter Build erfolgreich), &quot;gelb blinkend&quot; (Build / Tests laufen gerade) oder &quot;rot&quot; (Probleme beim letzter Build) schaltet.<br>
Die serielle Ansteuerung des Arduino erfolgt mittels des <a href="http://johnny-five.io">Johnny-Five IoT-Frameworks</a> Dieses Framework ist die einzige Dependency und stellt bereits eine Menge Funktionalität (Schieberegister, LCD-Ansteuerung, Animationen,...) von Haus aus bereit.</p>
<p>Das komplette Projekt habe ich unter MIT-Lizens auf meinem Github unter folgendem Link bereitgestellt: <a href="https://github.com/JohnnyDelphino/UnoJohnnyBuildInfo">UnoJohnnyBuildInfo</a>.<br>
Es wurde weitestgehend modularisiert, sodass sich die Teamcity-Anbindung über eine Config-Datei anpassen lässt und alle Dependencies in der <em>package.json</em> Datei verwaltet werden.<br>
Es soll lediglich einen Ansatz für künftige Modifikationen / Nachbauten liefern.</p>
<p>Falls ein Leser etwas ähnliches umsetzt, so kann er mich gerne anpingen.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[Build-Ampel] 3 Der finale Zusammenbau]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Im <a href="http://csdev.it/build-ampel-2-die-bauteile/">letzten Artikel</a> bin ich auf die verbauten Komponenten eingegangen. Hier soll es nun um den Zusammenbau aller Teile gehen.</p>
<p>Als erstes wurde die prototypische Schaltung vom Breadboard auf eine Lochrasterplatine übertragen, sprich die Mosfets, Jumper-Kabel und der 4-Pin-Molex-Anschluss miteinander verlötet.</p>
<p><img src="https://csdev.it/content/images/2016/07/loeten.jpg" alt="Bestücken der Platine"></p>
<p>Anstatt die Lampenfassungen direkt mit der Platine zu verlöten,</p>]]></description><link>https://csdev.it/build-ampel-3-der-finale-zusammenbau/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f0e</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Tue, 19 Jul 2016 14:08:42 GMT</pubDate><media:content url="https://csdev.it/content/images/2016/07/fertige_Schaltung.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://csdev.it/content/images/2016/07/fertige_Schaltung.jpg" alt="[Build-Ampel] 3 Der finale Zusammenbau"><p>Im <a href="http://csdev.it/build-ampel-2-die-bauteile/">letzten Artikel</a> bin ich auf die verbauten Komponenten eingegangen. Hier soll es nun um den Zusammenbau aller Teile gehen.</p>
<p>Als erstes wurde die prototypische Schaltung vom Breadboard auf eine Lochrasterplatine übertragen, sprich die Mosfets, Jumper-Kabel und der 4-Pin-Molex-Anschluss miteinander verlötet.</p>
<p><img src="https://csdev.it/content/images/2016/07/loeten.jpg" alt="[Build-Ampel] 3 Der finale Zusammenbau"></p>
<p>Anstatt die Lampenfassungen direkt mit der Platine zu verlöten, habe ich mich für <a href="https://de.wikipedia.org/wiki/L%C3%BCsterklemme">Lüsterklemmen</a> entschieden. Diese ermöglichen den schnellen Ausbau / Wechsel der Platine im Falle späterer Erweiterungen bzw. wenn Probleme auftreten sollten.</p>
<p><img src="https://csdev.it/content/images/2016/07/IMG_5058.JPG" alt="[Build-Ampel] 3 Der finale Zusammenbau"></p>
<p>Im unteren (grünen) Modul der Ampel wurde der Arduino und die Platine untergebracht, da hinter den Lampen jede Menge Platz vorhanden ist. Sowohl USB-Kabel des Arduino als auch der 12v Molex-Anschluss wurden durch den untern Arm der Ampel nach außen geführt.</p>
<p><img src="https://csdev.it/content/images/2016/07/led_lampe.jpg" alt="[Build-Ampel] 3 Der finale Zusammenbau"></p>
<p>Die Ampel ist insgesamt knapp einen Meter hoch. Auf dem folgenden Bild wird die Relation deutlich.</p>
<p><img src="https://csdev.it/content/images/2016/07/lampe_komplett.jpg" alt="[Build-Ampel] 3 Der finale Zusammenbau"></p>
<p>Im kommenden Artikel werde ich noch kurz auf die softwareseitige Ansteuerung der Ampel eingehen.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[Build-Ampel] 2 Die Bauteile]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Im <a href="http://csdev.it/build-ampel-1-die-projekt-idee/">ersten Beitrag</a> bin ich kurz auf die Projektidee eingegangen. An dieser Stelle soll es um die verbauten / benötigten Komponenten gehen.<br>
Zunächst werde ich aufführen, was in der fertigen Ampel verbaut wurde:</p>
<ul>
<li>Siemens Straßenampel (380V, e27-Lampenfassung)</li>
<li>Arduino Uno Microcontroller</li>
<li>3x <a href="https://www.amazon.de/gp/product/B015BAUUJ4/ref=oh_aui_detailpage_o01_s00?ie=UTF8&amp;psc=1">12v e27 LED-Lampe</a> -&gt; 3x 0.7A</li>
<li>3x <a href="https://www.amazon.de/gp/product/B00L8VC9TK/ref=oh_aui_detailpage_o04_s00?ie=UTF8&amp;psc=1">MOSFET</a></li></ul>]]></description><link>https://csdev.it/build-ampel-2-die-bauteile/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f0d</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Tue, 19 Jul 2016 11:02:23 GMT</pubDate><media:content url="https://csdev.it/content/images/2016/07/colors.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://csdev.it/content/images/2016/07/colors.jpg" alt="[Build-Ampel] 2 Die Bauteile"><p>Im <a href="http://csdev.it/build-ampel-1-die-projekt-idee/">ersten Beitrag</a> bin ich kurz auf die Projektidee eingegangen. An dieser Stelle soll es um die verbauten / benötigten Komponenten gehen.<br>
Zunächst werde ich aufführen, was in der fertigen Ampel verbaut wurde:</p>
<ul>
<li>Siemens Straßenampel (380V, e27-Lampenfassung)</li>
<li>Arduino Uno Microcontroller</li>
<li>3x <a href="https://www.amazon.de/gp/product/B015BAUUJ4/ref=oh_aui_detailpage_o01_s00?ie=UTF8&amp;psc=1">12v e27 LED-Lampe</a> -&gt; 3x 0.7A</li>
<li>3x <a href="https://www.amazon.de/gp/product/B00L8VC9TK/ref=oh_aui_detailpage_o04_s00?ie=UTF8&amp;psc=1">MOSFET</a></li>
<li>1x Lochrasterplatine</li>
<li>einige Jumperkabel / Kabel / Lötzinn</li>
<li>230v auf 12v Netzteil 2A (ursprünglich gedacht um PC-Festplatte extern anzuschließen) -&gt; perfekt für dieses Projekt geeignet.</li>
</ul>
<p><img src="https://csdev.it/content/images/2016/07/yellow.jpg" alt="[Build-Ampel] 2 Die Bauteile"></p>
<p>Die Ampel konnte ich günstig über eBay-Kleinanzeigen erwerben. Sie basiert auf 380Volt-Technik, was einige Dinge erschwert und ein Sicherheitsrisiko darstellt. Hier erfolgte, nach der initialen Reinigung, ein Umbau des gesamten Systems auf 12Volt-Technik (deshalb die oben aufgeführten 12V-Komponenten).</p>
<p>Ursprünglich hatte ich geplant LED-Matritzen zu löten und in die einzelnen Module zu verbauen. Da der Arduino jedoch nur eine geringe Anzahl an LEDs mit Strom versorgen kann hätte ich auch für diesen Ansatz eine externe Stromquelle benötigt. Als ich mich nach Alternativen umgeschaut habe, bin ich auf die 12v LED-Glühbirnen für e27-Fassung gestoßen, welche für den Camping-Bedarf gedacht sind, sich jedoch perfekt für mein Projekt eignen.  Da die Ampel bereits mit e27-Lampenfassungen ausgestattet ist, musste ich lediglich die Stromversorgung der Fassungen auf 12v anpassen.</p>
<p>Der Arduino Uno ist lediglich in der Lage 3,3v bzw. 5v bereit zu stellen. Für die 12v Spannungsversorgung erwies sich ein altes Netzteil (230v-&gt;12v-Trafo) als sehr nützlich das ursprünglich dafür gedacht war interne Festplatten extern anzuschließen. Es kann über einen (handelsüblichen PC-) 12v 4-Pin-Molex-Stromanschluss die benötigte Stromversorgung bereitstellen.<br>
Um Spannungen von 12v und mehr mit dem Arduino schalten zu können, habe ich <a href="https://de.wikipedia.org/wiki/Metall-Oxid-Halbleiter-Feldeffekttransistor">MOSFETs</a> verwendet. Sie ermöglichen es den Stromfluss mittels der Arduino Digital-Pins zu Kontrollieren (HIGH = Strom fliest, LOW = Strom unterbrochen).</p>
<p><img src="https://csdev.it/content/images/2016/07/breadboard.jpg" alt="[Build-Ampel] 2 Die Bauteile"></p>
<p>Um zu testen ob alles funktioniert wie geplant, habe ich die zugegeben einfache Schaltung erstmal auf einem Breadboard realisiert und mit den Komponenten der Ampel getestet.<br>
Nachdem alles funktionierte wie angedacht, wurde die Schaltung auf einer Lochrasterplatine realisiert. Dazu mehr im kommenden Artikel.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[Build-Ampel] 1 Die Projekt-Idee]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>RaspberryPi, Arduino und co. interessieren mich schon länger. Ich habe auch bereits an Workshops teilgenommen in denen kleinere Projekte umgesetzt wurden. Bisher hatte ich jedoch keine konkrete Idee, die ich umsetzen kann. Ich bin jedoch der festen Überzeugung, dass man am produktivsten ist und am meisten lernt, wenn man auf</p>]]></description><link>https://csdev.it/build-ampel-1-die-projekt-idee/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f0b</guid><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Sun, 19 Jun 2016 11:59:26 GMT</pubDate><media:content url="https://csdev.it/content/images/2016/05/sketch-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://csdev.it/content/images/2016/05/sketch-1.jpg" alt="[Build-Ampel] 1 Die Projekt-Idee"><p>RaspberryPi, Arduino und co. interessieren mich schon länger. Ich habe auch bereits an Workshops teilgenommen in denen kleinere Projekte umgesetzt wurden. Bisher hatte ich jedoch keine konkrete Idee, die ich umsetzen kann. Ich bin jedoch der festen Überzeugung, dass man am produktivsten ist und am meisten lernt, wenn man auf ein konkretes Ziel hinarbeitet.</p>
<p>Ich habe vor Jahren einen RaspberryPi der ersten Generation (256MB RAM) gekauft. Dieser war anfangs als Kodi-Mediacenter im Einsatz, verstaubt jedoch seit einiger Zeit im Regal. Was wäre also naheliegender als ihn für dieses Projekt als Controller zu benutzen. Dies war zumindest der ursprüngliche Plan.<br>
Ok, Raspberry rausgekramt,  Raspbian Linux installiert - Ready. Mir fehlten jedoch noch Komponenten (LEDs, Widerstände etc) um mit dem Experimentieren zu starten. Daraufhin habe ich mir das Sunfounder Super-Kit bestellt. Dieses umfasst vom Breadboard über LEDs, 7-Segmentanzeigen bis hin zum LCD alles was man für den Start braucht.</p>
<p>Während ich auf das Komponenten-Kit wartete bin ich noch sehr günstig an einen Arduino Uno gekommen. Ich begann damit zu &quot;spielen&quot; und als das Kit ankam ein paar Schaltungen für den Arduino zu bauen.</p>
<p><img src="https://csdev.it/content/images/2016/06/pi_un_arduino.jpg" alt="[Build-Ampel] 1 Die Projekt-Idee"></p>
<h3 id="dasprojekt">Das Projekt</h3>
<p>Da ich mich in meinem Job aktuell intensiv mit Continuous Integration auseinander setze, hat sich die Projekt-Idee entwickelt eine &quot;Build-Ampel&quot; zu bauen, welche auf einfache Weise visualisiert, ob ein Build aktuell läuft, fehlgeschlagen ist oder erfolgreich war. Ein gutes Thema für den Einstieg, welches sich beliebig erweitern lässt.</p>
<p><img src="https://csdev.it/content/images/2016/06/trafficlight_basic.png" alt="[Build-Ampel] 1 Die Projekt-Idee"></p>
<p>Der Grundaufbau besteht aus einem Microcontroller (RaspberryPi / Arduino / etc.) welcher die Ampel entsprechend der Build-Informationen schaltet. Die Daten werden per Rest-API vom Build-Server geladen und dann verarbeitet.<br>
Dies stellt lediglich den Basis-Aufbau dar. Man kann die Konstruktion beliebig erweitern. Denkbar wäre beispielsweise eine Uhr, die die Buildzeit darstellt, ein Lautsprecher, der auf den fertigen / fehlgeschlagenen Build hinweist, ....</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[About]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Nach Jahren beginne ich mal wieder mit dem Bloggen. Hier soll es vor allem darum gehen Projekte / Ideen festzuhalten und zu dokumentieren.<br>
Die Blogging-Plattform Ghost, welche ich hier verwende, eignet sich hervorragend dafür. Sie bietet ein schlankes Frontend zum bloggen und nutzt den z.B. von Github bekannten Markdown-Syntax zur</p>]]></description><link>https://csdev.it/welcome-to-ghost/</link><guid isPermaLink="false">5f675ae7a9c57351b3520f08</guid><category><![CDATA[Getting Started]]></category><dc:creator><![CDATA[Christian Schäfer]]></dc:creator><pubDate>Mon, 16 May 2016 19:50:21 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Nach Jahren beginne ich mal wieder mit dem Bloggen. Hier soll es vor allem darum gehen Projekte / Ideen festzuhalten und zu dokumentieren.<br>
Die Blogging-Plattform Ghost, welche ich hier verwende, eignet sich hervorragend dafür. Sie bietet ein schlankes Frontend zum bloggen und nutzt den z.B. von Github bekannten Markdown-Syntax zur Auszeichnung von Blog-Posts.</p>
<p>Kommentare sind ausdrücklich erwünscht. Dafür wurde Disqus eingebunden, was sich Blogging-Platform-übergreifend etabliert hat und autonom von der Plattform ist. Sollte ich also später ein mal Ghost den Rücken kehren und auf eine neue Plattform einsetzen kann ich alle Kommentare problemlos umziehen.</p>
<p>Ok dies war es auch schon mit dem Vorgeplänkel. Ab jetzt Content :-)</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>