<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.7.6(BH)" -->
<rss version="2.0">
    <channel xmlns:g="http://base.google.com/ns/1.0">
        <title>Planet Maemo: category &quot;feed:766d7361580352c5efed0204e4ba8593&quot;</title>
        <description>Blog entries from Maemo community</description>
        <link>http://maemo.org/news/planet-maemo/</link>
        <lastBuildDate>Sun, 24 May 2026 14:05:40 +0000</lastBuildDate>
        <generator>FeedCreator 1.7.6(BH)</generator>
        <language>en</language>
        <managingEditor>planet@maemo.org</managingEditor>
        <item>
            <title>Mobile blogging, the past and the future</title>
            <link>https://bergie.iki.fi/blog/mobile-blogging/</link>
            <description><![CDATA[
<p>This blog has been running more or less continuously since mid-nineties. The site has existed in multiple forms, and with different ways to publish. But what’s common is that at almost all points there was a mechanism to publish while on the move.</p>

<h2 id="psion-documents-over-ftp">Psion, documents over FTP</h2>

<p>In the early 2000s we were into adventure motorcycling. To be able to share our adventures, we implemented a way to publish blogs while on the go. The device that enabled this was the <a href="https://en.wikipedia.org/wiki/Psion_Series_5">Psion Series 5</a>, a handheld computer that was very much a device ahead of its time.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/psions5.jpg" alt="Psion S5, also known as the Ancestor" /></p>

<p>The Psion had a reasonably sized keyboard and a good native word processing app. And battery life good for weeks of usage. Writing while underway was easy. The Psion could use a mobile phone as a modem over an infrared connection, and with that we could upload the documents to a server over FTP.</p>

<p>Server-side, a cron job would grab the new documents, converting them to HTML and adding them to our CMS.</p>

<p>In the early days of GPRS, getting this to work while roaming was quite tricky. But the system served us well for years.</p>

<p>If we wanted to include photos to the stories, we’d have to find an Internet cafe.</p>

<ul>
  <li><a href="https://bergie.iki.fi/blog/to-to-alps/">To the Alps</a> is a post from these times. Lots more in the <a href="https://bergie.iki.fi/blog/category/motorcycles/">motorcycling category</a></li>
</ul>

<h2 id="sms-and-mms">SMS and MMS</h2>

<p>For an even more mobile setup, I implemented an SMS-based blogging system. We had an old phone connected to a computer back in the office, and I could write to my blog by simply sending a text. These would automatically end up as a new paragraph in the latest post. If I started the text with <code class="language-plaintext highlighter-rouge">NEWPOST</code>, an empty blog post would be created with the rest of that message’s text as the title.</p>

<ul>
  <li><a href="https://bergie.iki.fi/blog/in-the-caucasus/">In the Caucasus</a> is a good example of a post from this era</li>
</ul>

<p>As I got into <a href="https://bergie.iki.fi/blog/category/geo/">neogeography</a>, I could also send a <code class="language-plaintext highlighter-rouge">NEWPOSITION</code> message. This would update my position on the map, connecting weather metadata to the posts.</p>

<p>As camera phones became available, we wanted to do pictures too. For the Death Monkey rally where we rode minimotorcycles from Helsinki to Gibraltar, we implemented an MMS-based system. With that the entries could include both text and pictures. But for that you needed a gateway, which was really only realistic for an event with sponsors.</p>

<ul>
  <li><a href="https://web.archive.org/web/20061013183009/http://www.deathmonkey.org/view/mystery-of-the-missing-monkey.html">Mystery of the Missing Monkey</a> is typical. Some more in <a href="https://web.archive.org/web/20060804205237/http://www.deathmonkey.org/">Internet Archive</a></li>
</ul>

<h2 id="photos-over-email">Photos over email</h2>

<p>A much easier setup than MMS was to slightly come back to the old Psion setup, but instead of word documents, sending email with picture attachments. This was something that the new breed of (pre-iPhone) smartphones were capable of. And by now the roaming question was mostly sorted.</p>

<p>And so my blog included a new “moblog” section. This is where I could share my daily activities as poor-quality pictures. Sort of how people would use Instagram a few years later.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/bergie_layout_2006.jpg" alt="My blog from that era" /></p>

<ul>
  <li><a href="https://web.archive.org/web/20110604011733/http://bergie.iki.fi/moblog">Internet Archive has some of my old moblogs</a> but nowadays, I post similar stuff <a href="https://pixelfed.de/bergie">on Pixelfed</a></li>
</ul>

<h2 id="pause">Pause</h2>

<p>Then there was sort of a long pause in mobile blogging advancements. Modern smartphones, data roaming, and WiFi hotspots had become ubiquitous.</p>

<p>In the meanwhile the blog also got <a href="https://bergie.iki.fi/blog/blog-2012-edition/">migrated to a Jekyll-based system</a> hosted on AWS. That means the old Midgard-based integrations were off the table.</p>

<p>And I traveled off-the-grid rarely enough that it didn’t make sense to develop a system.</p>

<p>But now that we’re <a href="https://lille-oe.de">sailing offshore</a>, that has changed. Time for new systems and new ideas. Or maybe just a rehash of the old ones?</p>

<h2 id="starlink-internet-from-outer-space">Starlink, Internet from Outer Space</h2>

<p>Most cruising boats - ours included - now run the Starlink satellite broadband system. This enables full Internet, even in the middle of an ocean, even video calls! With this, we can use normal blogging tools. The usual one for us is <a href="https://gitjournal.io">GitJournal</a>, which makes it easy to write Jekyll-style Markdown posts and push them to GitHub.</p>

<p>However, Starlink is a complicated, energy-hungry, and fragile system on an offshore boat. The policies might change at any time preventing our way of using it, and also the dishy itself, or the way we power it may fail.</p>

<p>But despite what you’d think, even on a nerdy boat like ours, loss of Internet connectivity is not an emergency. And this is where the old-style mobile blogging mechanisms come handy.</p>

<ul>
  <li>Any of the <a href="https://lille-oe.de/2025/">2025 Atlantic crossing posts</a> is a good example of this setup in action</li>
</ul>

<h2 id="inreach-texting-with-the-cloud">Inreach, texting with the cloud</h2>

<p>Our backup system to Starlink is the Garmin Inreach. This is a tiny battery-powered device that connects to the Iridium satellite constellation. It allows tracking as well as basic text messaging.</p>

<p>When we head offshore we always enable tracking on the Inreach. This allows both our blog and our friends ashore to follow our progress.</p>

<p>I also made a simple integration where text updates sent to <a href="https://share.garmin.com/home">Garmin MapShare</a> get fetched and published on our blog. Right now this is just plain text-based entries, but one could easily implement a command system similar to what I had over SMS back in the day.</p>

<p>One benefit of the Inreach is that we can also take it with us when we go on land adventures. And it’d even enable rudimentary communications if we found ourselves in a liferaft.</p>

<ul>
  <li>There are <a href="https://github.com/tabeaeggler/MarineGRIB-InReach-Transmitter">various InReach integration hacks</a> that could be used for more sophisticated data transfer</li>
</ul>

<h2 id="sailmail-and-email-over-hf-radio">Sailmail and email over HF radio</h2>

<p>The other potential backup for Starlink failures would be to go seriously old-school. It is possible to get email access via a SSB radio and a Pactor (or <a href="https://rosmodem.wordpress.com">Vara</a>) modem.</p>

<p>Our boat is already equipped with an isolated aft stay that can be used as an antenna. And with the popularity of Starlink, many cruisers are offloading their old HF radios.</p>

<p>Licensing-wise this system could be used either as a marine HF radio (requiring a Long Range Certificate), or amateur radio. So that part is something I need to work on. Thankfully post-COVID, radio amateur license exams can be done online.</p>

<p>With this setup we could send and receive text-based email. The <a href="https://sailmail.com">Airmail</a> application used for this can even do some automatic templating for position reports. We’d then need a mailbox that can receive these mails, and some automation to fetch and publish.</p>

<ul>
  <li><a href="https://www.sailblogs.com/wiki/index.php/Using_SailBlogs_Remote">Sailmail</a> and <a href="https://www.noforeignland.com/help/boat/move-email">No Foreign Land</a> support structured data via email to update position. Their formats could be useful inspiration</li>
</ul>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1f0425240e0b89a425211f0ba29830306e4dec9dec9&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1f0425240e0b89a425211f0ba29830306e4dec9dec9/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1f0425240e0b89a425211f0ba29830306e4dec9dec9&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1f0425240e0b89a425211f0ba29830306e4dec9dec9/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1f0425240e0b89a425211f0ba29830306e4dec9dec9</guid>
        </item>
        <item>
            <title>Managing a developer shell with Docker</title>
            <link>https://bergie.iki.fi/blog/docker-developer-shell/</link>
            <description><![CDATA[
<p>When I’m not in <a href="https://flowhub.io/ide/">Flowhub-land</a>, I’m used to developing software in a quite customized command line based development environment. Like for many, the cornerstones of this for me are <a href="https://www.vim.org">vim</a> and <a href="https://github.com/tmux/tmux/wiki">tmux</a>.</p>

<p>As customization increases, it becomes important to have a way to manage that and distribute it across the different computers. For years, I’ve used a <a href="https://github.com/bergie/dotfiles">dotfiles repository</a> on GitHub together with <a href="https://www.gnu.org/software/stow/">GNU Stow</a> for this.</p>

<p>However, this still means I have to install all the software and tools before I can have my environment up and running.</p>

<h2 id="using-docker">Using Docker</h2>

<p><a href="https://www.docker.com">Docker</a> is a tool for building and running software in a containerized fashion. Recently <a href="https://github.com/tiagodeoliveira">Tiago</a> gave me the inspiration to use Docker not only for distributing production software, but also for actually running my development environment.</p>

<p>Taking ideas from <a href="https://github.com/tiagodeoliveira/docker-shell">his setup</a>, I built upon my existing dotfiles and built a <a href="https://hub.docker.com/r/bergie/shell/">reusable developer shell container</a>.</p>

<p>With this, I only need Docker installed on a machine, and then I’m two commands away from having my normal development environment:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>docker volume create workstation
<span class="nv">$ </span>docker run <span class="nt">-v</span> ~/Projects:/projects <span class="nt">-v</span> workstation:/root <span class="nt">-v</span> ~/.ssh:/keys <span class="nt">--name</span> workstation <span class="nt">--rm</span> <span class="nt">-it</span> bergie/shell
</code></pre></div></div>

<p>Here’s how it looks in action:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/800x/vim-developer-shell-docker.png" alt="Working on NoFlo inside Docker shell" /></p>

<p>Once I update my Docker setup (for example to install or upgrade some tool), I can get the latest version on a machine with:</p>

<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>docker pull bergie/shell
</code></pre></div></div>

<p>At least in theory this should give me a fully identical working environment regardless of the host machine. Linux VPS, a MacBook, or a Windows machine should all be able to run this. And soon, this should also work out of the box <a href="https://chromeunboxed.com/news/chromebook-containers-virtual-machine-crostini-google-io">on Chromebooks</a>.</p>

<h2 id="setting-this-up">Setting this up</h2>

<p>The basics are pretty simple. I already had a repository for my dotfiles, so I only needed to write <a href="https://github.com/bergie/dotfiles/blob/master/Dockerfile">a Dockerfile</a> to install and set up all my software.</p>

<p>To make things even easier, I <a href="https://github.com/bergie/dotfiles/blob/master/.travis.yml">configured Travis</a> so that every time I push some change to the dotfiles repository, it will create and publish a new container image.</p>

<h2 id="further-development-ideas">Further development ideas</h2>

<p>So far this setup seems to work pretty well. However, here are some ideas for further improvements:</p>

<ul>
  <li><strong>ARM build</strong>: Sometimes I need to work on Raspberry Pis. It might be nice to cross-compile an ARM version of the same setup</li>
  <li><strong>Key management</strong>: Currently I create new SSH keys for each host machine, and then upload them to the relevant places. With this setup I could use a USB stick, or maybe even a <a href="https://www.yubico.com/products/yubikey-hardware/">Yubikey</a> to manage them</li>
  <li><strong>Application authentication</strong>: Since the Docker image is public, it doesn’t come with any secrets built in. This means I still need to authenticate with tools like NPM and Travis. It might be interesting to manage these together with my SSH keys</li>
  <li><strong>SSH host</strong>: with some tweaking it might be possible to run the same container on cloud services. Then I’d need a way to get my SSH public keys there and start an SSH server</li>
</ul>

<p>If you have ideas on how to best implement the above, please <a href="mailto:henri.bergius@iki.fi">get in touch</a>.</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e844016ef14fb2440111e8b7c1e7fd7082a18da18d&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e844016ef14fb2440111e8b7c1e7fd7082a18da18d/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e844016ef14fb2440111e8b7c1e7fd7082a18da18d&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e844016ef14fb2440111e8b7c1e7fd7082a18da18d/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 19 Apr 2018 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e844016ef14fb2440111e8b7c1e7fd7082a18da18d</guid>
        </item>
        <item>
            <title>Atreus: Building a custom ergonomic keyboard</title>
            <link>https://bergie.iki.fi/blog/atreus-build-log/</link>
            <description><![CDATA[
<p>As mentioned in my <a href="https://bergie.iki.fi/blog/working-on-android-2017/">Working on Android post</a>, I’ve been using a mechanical keyboard for a couple of years now. Now that I work <a href="https://bergie.iki.fi/blog/flowhub-ug/">on Flowhub</a> from home, it was a good time to re-evaluate the whole work setup. As far as regular keyboards go, the MiniLa was nice, but I wanted something more compact and ergonomic.</p>

<h2 id="the-atreus-keyboard">The Atreus keyboard</h2>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/ready-2.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/ready-2-small.jpg" alt="My new Atreus" /></a></p>

<p>Atreus is a 40% ergonomic mechanical keyboard designed by <a href="https://technomancy.us/">Phil Hagelberg</a>. It is an <a href="https://github.com/technomancy/atreus">open hardware design</a>, but he also <a href="https://atreus.technomancy.us/">sells kits</a> for easier construction. From the kit introduction:</p>

<blockquote>
  <p>The Atreus is a small mechanical keyboard that is based around the shape of the human hand. It combines the comfort of a split ergonomic keyboard with the crisp key action of mechanical switches, all while fitting into a tiny profile.</p>
</blockquote>

<p>My use case was also quite travel-oriented. I wanted a small keyboard that would enable me to work with it also on the road. There are many other small-ish DIY keyboard designs like <a href="https://olkb.com/planck/">Planck</a> and <a href="http://www.40percent.club/2016/11/gherkin.html">Gherkin</a> available, but Atreus had the advantage of better ergonomics. I really liked the design of the <a href="https://www.ergodox.io">Ergodox</a> keyboard, and Atreus essentially is <a href="https://technomancy.us/173">that made mobile</a>:</p>

<blockquote>
  <p>I found the split halves and relatively large size (which are fantastic for stationary use at a desk) make me reluctant to use it on the lap, at a coffee shop, or on the couch, so that’s the primary use case I’ve targeted with the Atreus. It still has most of the other characteristics that make the Ergodox stand out, like mechanical Cherry switches, staggered columns instead of rows, heavy usage of the thumbs, and a hackable microcontroller with flexible firmware, but it’s dramatically smaller and lighter</p>
</blockquote>

<p>I had the opportunity to try a kit-built Atreus in the <a href="https://www.meetup.com/Berlin-Mechanical-Keyboards-Input-Devices-Meetup/">Berlin Mechanical Keyboard meetup</a>, and it felt nice. It was time to start the project.</p>

<h2 id="sourcing-the-parts">Sourcing the parts</h2>

<p>When building an Atreus the first decision is whether to go with the kit or <a href="http://imgur.com/a/qcgdF">hand-wire it yourself</a>. Building from a kit is certainly easier, but since I’m a member of <a href="https://c-base.org/">a hackerspace</a>, doing a hand-wired build seemed like the way to go.</p>

<p>To build a custom keyboard, you need:</p>

<ul>
  <li>Switches: in my case 37 Cherry MX blues and 5 Cherry MX blacks</li>
  <li>Diodes: one 1N4148 per switch</li>
  <li>Microcontroller: a Arduino Pro Micro on my keyboard</li>
  <li>Keycaps: started with recycled ones and later upgraded to DSA blanks</li>
  <li>Case: got a set of laset-cut steel plates</li>
</ul>

<p>Even though Cherry — the maker of the most common mechanical key switches — is a German company, it is quite difficult to get switches in retail here. Luckily a fellow hackerspace member had just dismantled some old mechanical keyboards, and so I was able to get the switches I needed via barter.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/keyswitches.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/keyswitches-small.jpg" alt="Keyswitches" /></a></p>

<p>The Cherry MX blues are tactile clicky switches that feel super-nice to type on, but are quite loud. For modifiers I went with Cherry MX blacks that are linear. This way there is quite a clear difference in feel between keys you typically hold down compared to the ones you just press.</p>

<p>The diodes and the microcontroller I ordered from Amazon for about 20€ total.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/microcontroller.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/microcontroller-small.jpg" alt="Arduino Pro Micro" /></a></p>

<p>At first I used a set of old keycaps that I got with the switches, but once the keyboard was up and running I upgraded to a very nice set of blank DSA-profile keycaps that I ordered <a href="https://www.aliexpress.com/store/2230037">from AliExpress</a> for 30€. That set came with enough keycaps that I’ll have myself covered if I ever build a second Atreus.</p>

<p>All put together, I think the parts ended up costing me around 100€ total.</p>

<h2 id="preparations">Preparations</h2>

<p>When I received all the parts, there were some preparation steps to be made. Since the key switches were 2nd hand, I had to start by dismantling them and removing old diodes that had been left inside some of them.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/keyswitches-prep.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/keyswitches-prep-small.jpg" alt="Opening the key switches" /></a></p>

<p>The keycaps I had gotten with the switches were super grimy, and so I ended up sending them to the washing machine. After that you could see that they were not new, but at least they were clean.</p>

<p>With the steel mounting plate there had been a slight misunderstading, and the plates I received were a few millimeters thicker than needed, so the switches wouldn’t “click” in place. While this could’ve been worked around with hot glue, we ended up filing the mounting holes down to the right thickness.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/filing-plate-1.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/filing-plate-1-small.jpg" alt="Filing the plate" /></a></p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/filing-plate-2.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/filing-plate-2-small.jpg" alt="Little bit of help" /></a></p>

<h2 id="wiring-the-keyboard">Wiring the keyboard</h2>

<p>Once the mounting plate was in the right shape, I clicked the switches in and it was time to solder.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/switches-mounted.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/switches-mounted-small.jpg" alt="All switches in place" /></a></p>

<p>Hand-wiring keyboards is not that tricky. You have to attach a diode to each keyswitch, and then connect each row together via the diodes.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/diode-rows-1.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/diode-rows-1-small.jpg" alt="Connecting diodes" /></a></p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/diode-rows-2.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/diode-rows-2-small.jpg" alt="First row ready" /></a></p>

<p>The two thumb keys are wired to be on the same column, but different rows.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/diode-rows-3.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/diode-rows-3-small.jpg" alt="All rows ready diodes" /></a></p>

<p>Then each column is connected together via the other pin on the switches.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/columns.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/columns-small.jpg" alt="Soldering columns" /></a></p>

<p>This is how the matrix looks like:</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/wiring-ready.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/wiring-ready-small.jpg" alt="Completed matrix" /></a></p>

<p>After these are done, connect a wire from each column, and each row to a I/O pin on the microcontroller.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/soldering.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/soldering-small.jpg" alt="Adding column wires" /></a></p>

<p>If you haven’t done it earlier, this is a good stage to test all connections with a multimeter!</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/soldering-microcontroller.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/soldering-microcontroller-small.jpg" alt="Connecting the microcontroller" /></a></p>

<h2 id="firmware">Firmware</h2>

<p>After finishing the wiring, I downloaded the <a href="https://github.com/qmk/qmk_firmware">QMK firmware</a>, changed the <a href="https://github.com/bergie/qmk_firmware/commit/1902fc2affcd4cb1cbe2225b8c0736f57eca5646">PIN mapping</a> for how my Atreus is wired up, switched the layout to <a href="https://colemak.com/">Colemak</a>, and the keyboard was ready to go.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/ready-1.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/ready-1-small.jpg" alt="Atreus in use" /></a></p>

<p>Don’t mind the key labels in the picture above. These are the second-hand keycaps I started with. Since then I’ve switched to <a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/ready-2.jpg">blank ones</a>.</p>

<h2 id="usb-c">USB-C</h2>

<p>The default Atreus design has the USB cable connected directly to the microcontroller, meaning that you’ll have to open the case to change the cable. To mitigate that I wanted to add a USB breakout board to the project, and this being 2017, it felt right to go with <a href="https://en.wikipedia.org/wiki/USB-C">USB-C</a>.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/usb-breakout.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/usb-breakout-small.jpg" alt="USB-C breakouts" /></a></p>

<p>I found some cheap USB-C breakout boards from AliExpress. Once they arrived, it was time to figure out how the spec works. Since USB-C is quite new, there are very few resources available on how to use it with microcontrollers. These tutorials were quite helpful:</p>

<ul>
  <li><a href="https://www.scorpia.co.uk/2016/03/17/using-usb-type-c-on-hobyist-projects/">Using USB-C on hobbyist projects</a></li>
  <li><a href="http://www.embedded.com/electronics-blogs/benson-s-blocks/4442214/USB-Type-C-in-a-Micro-B-world">USB Type C in a Micro-B world</a></li>
</ul>

<p>Here is how we ended up wiring the breakout board. After these you only have four wires to connect to the microcontroller: ground, power, and the positive and negative data pins.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/usb-breakout-wired.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/usb-breakout-wired-small.jpg" alt="USB-C breakout with wiring" /></a></p>

<p><a href="https://sgotti.me/post/atreus-keyboard-build-log/">This Atreus build log</a> was useful for figuring out where to connect the USB wires on the Pro Micro. Once all was done, I had a custom, USB-C keyboard!</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/usb-ready.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/usb-ready-small.jpg" alt="USB-C keyboard" /></a></p>

<h2 id="next-steps">Next steps</h2>

<p>Now I have the Atreus working nicely on my new standing desk. Learning Colemak is a bit painful, but the keyboard itself feels super nice!</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/standing-desk.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/atreus-build/standing-desk-small.jpg" alt="New standing desk" /></a></p>

<p>However, I’d still like to CNC mill a proper wooden case for the keyboard. I may update this post once that happens.</p>

<p>I’m also considering to order an <a href="https://atreus.technomancy.us/">Atreus kit</a> so I’d have a second, always packed for travel keyboard. The kit comes with a PCB, which might work better at airport security checks than the hand-wired build.</p>

<p>Another thing that is quite tempting is to make a custom firmware with <a href="http://microflo.org/">MicroFlo</a>. I have no complaints on how QMK works, but it’d be super-cool to use our <a href="https://flowhub.io/">visual programming tool</a> to tweak the keyboard live.</p>

<p>Big thanks to <a href="http://github.com/technomancy">Technomancy</a> for the Atreus design, and to XenGi for all the help during the build!</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a463b1020de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a463b1020de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a463b1020de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a463b1020de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 20 Apr 2017 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a463b1020de9a11e7894e07d57c4b55bb55bb</guid>
        </item>
        <item>
            <title>Working on an Android tablet, 2017 edition</title>
            <link>https://bergie.iki.fi/blog/working-on-android-2017/</link>
            <description><![CDATA[
<p>Back in 2013 I was <a href="https://bergie.iki.fi/blog/working-on-android/">working exclusively on an Android tablet</a>. Then with the <a href="https://bergie.iki.fi/blog/noflo-kickstarter-launch/">NoFlo Kickstarter</a> I needed a device with a desktop browser. What followed were brief periods working on a Chromebook, on a 12” MacBook, and even an iPad Pro.</p>

<p>But from April 2016 onwards I’ve been again working with an Android device. Some people have asked me about my setup, and so here is an update.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_travelers_notebook.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_travelers_notebook_small.jpg" alt="Information technology" /></a></p>

<h2 id="why-work-on-a-tablet">Why work on a tablet?</h2>

<p>When I started on this path in 2013, using a tablet for “real work” was considered crazy. While every story on tablet productivity still brings out the people claiming <em>it is not a real computer for real work</em>, using <em>tablets for real work</em> is becoming more and more common.</p>

<p>A big contributor to this has been the plethora of work-oriented tablets and convertibles released since then. Microsoft’s popular <a href="https://en.m.wikipedia.org/wiki/Microsoft_Surface">Surface Pro line</a> brought the PC to tablet form factor, and Apple’s <a href="https://en.m.wikipedia.org/wiki/IPad_Pro">iPad Pro devices</a> gave the iPad a keyboard.</p>

<p>Here are couple of great posts talking about how it feels to work on an iPad:</p>

<ul>
  <li><a href="http://mattgemmell.com/rediscovering-the-ipad/">Rediscovering the iPad</a></li>
  <li><a href="http://www.macworld.com/article/3130710/ios/when-traveling-my-ipad-is-essential-and-my-mac-is-the-add-on.html">When traveling, my iPad is essential and my Mac is the add-on</a></li>
  <li><a href="https://www.macstories.net/stories/one-year-of-ipad-pro/">A Computer for Everything: One Year of iPad Pro</a></li>
  <li><a href="https://brooksreview.net/2016/12/evovling-ipad-desktop-usage/">Evolving iPad Desktop Usage</a></li>
  <li><a href="https://medium.learningbyshipping.com/my-tablet-has-stickers-8f7ab9022ebd#.vqpn9n2fi">My Tablet Has Stickers</a></li>
</ul>

<p>With all the activity going on, one could claim using a tablet for work has been normalized. But why work on a tablet instead of a “real computer”? Here are some reasons, at least for me:</p>

<h3 id="free-of-legacy-cruft">Free of legacy cruft</h3>

<p>Desktop operating systems have become clunky. Window management. File management. Multiple ways to discover, install, and uninstall applications. Broken notification mechanisms.</p>

<p>With a tablet you can bypass pretty much all of that, and jump into a simpler, cleaner interface designed for the modern connected world.</p>

<p>I think this is also the reason driving some developers back to Linux and <a href="http://swaywm.org">tiling window managers</a> — cutting manual tweaking and staying focused.</p>

<h3 id="amazing-endurance">Amazing endurance</h3>

<p>Admittedly, laptop battery life has increased a lot since 2013. But with some manufacturers using this an excuse to ship thinner devices, tablets still win the endurance game.</p>

<p>With my current work tablet, I’m customarily getting 12 or more hours of usage. This means I can power through the typical long days of a startup founder without having to plug in. And when traveling, I really don’t have to care where power sockets are located on trains, airplanes, and conference centers.</p>

<p>Low power usage also means that I can really get a lot of more runtime by utilizing the <a href="http://www.macworld.com/article/3034575/hardware/anker-powercore-20100-review-a-top-performing-usb-c-battery-pack.html">mobile battery pack</a> I originally bought to use with my phone. While I’ve never actually had to try this, back-of-the-envelope math claims I should be able to get a full workweek from the combo without plugging in.</p>

<h3 id="work-and-play">Work and play</h3>

<p>The other aspect of using a tablet is that it becomes a very nice content consumption device after I’m done working. Simply disconnect the keyboard and lean back, and the same device you used for writing software becomes a great e-reader, video player, or a gaming machine.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_spacex.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_spacex_small.jpg" alt="Livestreaming a SpaceX launch" /></a></p>

<p>This combined with the battery life has meant that I’ve actually stopped carrying a Kindle with me. While an e-ink screen is still nicer to read, not needing an extra device has its benefits, especially for a frequent one-bag traveller.</p>

<h2 id="the-setup">The setup</h2>

<p>I’m writing this on a <a href="https://en.m.wikipedia.org/wiki/Pixel_C">Pixel C</a>, a 10.2” Android tablet made by Google. I got the device last spring when there were developer discounts available at ramp-up to the Android 7 release, and have been using it full-time since.</p>

<h3 id="software">Software</h3>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/android_homescreen_2017.png"><img src="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/android_homescreen_2017_small.png" alt="My Android homescreen" /></a></p>

<p>Surprisingly little has changed in my software use <a href="https://bergie.iki.fi/blog/working-on-android/">since 2013</a> — I still spend the most of the time writing software in either <a href="https://flowhub.io">Flowhub</a> or terminal. Here are the apps I use on daily basis:</p>

<ul>
  <li><a href="https://play.google.com/store/apps/details?id=com.sonelli.juicessh">JuiceSSH</a> for mosh access to my remote development servers</li>
  <li><a href="https://play.google.com/store/apps/details?id=com.termux">Termux</a> for local and offline development</li>
  <li><a href="https://flowhub.io">Flowhub</a> for visual programming</li>
  <li><a href="https://play.google.com/store/apps/details?id=io.thegrid.app">The Grid</a> for updating my various websites</li>
  <li><a href="https://play.google.com/store/apps/details?id=com.Slack">Slack</a>, <a href="https://play.google.com/store/apps/details?id=com.google.android.talk">Hangouts</a>, and <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.inbox">Inbox by Gmail</a> for communications</li>
  <li><a href="https://play.google.com/store/apps/details?id=com.google.android.apps.docs">Google Drive</a> and the associated applications for budgeting and planning</li>
  <li><a href="https://play.google.com/store/apps/details?id=com.android.chrome">Chrome</a> for web</li>
</ul>

<p>Looking back to the situation in early 2013, the biggest change is that <strong>Slack</strong> has pretty much killed work email.</p>

<p><strong>Termux</strong> is a new app that has done a lot to improve the local development situation. By starting the app you get a very nice Linux chroot environment where a lot of software is only a quick <code class="language-plaintext highlighter-rouge">apt install</code> away.</p>

<p>Since much of my non-Flowhub work is done in <em>tmux</em> and <em>vim</em>, I get the exactly same working environment on both local chroot and cloud machines by simply installing <a href="https://github.com/bergie/dotfiles">my dotfiles</a> on each of them.</p>

<h3 id="keyboard">Keyboard</h3>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_laptop.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_laptop_small.jpg" alt="Laptop tablet" /></a></p>

<p>When I’m on the road I’m using the <a href="http://www.anandtech.com/show/9972/the-google-pixel-c-review/7">Pixel C keyboard</a>. This doubles as a screen protector, and provides a reasonable laptop-like typing environment. It attaches to the tablet with very strong magnets and allows a good amount of flexibility on the screen angles.</p>

<p>However, when stationary, no laptop keyboard compares to a real mechanical keyboard. When I’m in the office I use a <a href="http://www.cultofmac.com/290750/filco-minila-air-bluetooth-keyboard-review/">Filco MiniLa Air</a>, a bluetooth keyboard with quiet-ish Cherry MX brown switches.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_desktop.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_desktop_small.jpg" alt="Desktop tablet" /></a></p>

<p>This tenkeyless (60%) keyboard is extremely comfortable to type on. However, the sturdy metal case means that it is a little too big and heavy to carry on a daily basis.</p>

<p>In practice I’ve only taken the mechanical keyboard with me when there has been a longer trip where I know that I’ll be doing a lot of typing. To solve this, I’m actually <a href="https://www.instagram.com/p/BP0lNxJDng_/?taken-by=henribergius">looking to build</a> a more compact custom mechanical keyboard so I could always have it with me. (<strong>Update</strong>: <a href="http://bergie.iki.fi/blog/atreus-build-log/">here is the keyboard I built</a>).</p>

<h2 id="comparison-with-ios">Comparison with iOS</h2>

<p>So, why work on Android instead of getting an iPad Pro? I’ve actually worked on both, and here are my reasons:</p>

<ul>
  <li><strong>Communications between apps</strong>: while iOS has extensions now, the ability to send data from an app to another is still a hit-or-miss. Android had intents from day one, meaning pretty much any app can talk to any other app</li>
  <li><strong>Standard charging</strong>: all of my other devices charge with the same USB-C chargers and cables. iPads still use the proprietary Lightnight plug, requiring custom dongles for everything</li>
  <li><strong>Standard accessories</strong>: this boils down to USB-C just like charging. With Android I can plug in a network adapter or even a mouse, and it’ll just work</li>
  <li><strong>Ecosystem lock-in</strong>: we’re moving to a world where everything — from household electronics to cars — is either locked to the Apple ecosystem or following standards. I don’t want to be locked to a single vendor for everything digital</li>
  <li><strong>Browser choice</strong>: with iOS you only get one web renderer, the rather dated Safari. On Android I can choose between Chrome, Firefox, or any other browser that has been ported to the platform</li>
</ul>

<p>Of course, iOS has its own benefits. Apple has a stronger stance on privacy than Google. And there is more well-made tablet software available for iPads than Android. But when almost everything I use is available on the web, this doesn’t matter that much.</p>

<h2 id="the-future">The future</h2>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_cbase.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/android-tablet-2017/pixel_c_cbase_small.jpg" alt="Hacking on the c-base patio" /></a></p>

<p>As a software developer working on Android tablets, the weakest point of the platform is still that there are <em>no browser developer tools</em> available. This was a problem in 2013, and it is still a problem now.</p>

<p>From my conversations with some Chrome developers, it seems Google has very little interest in addressing this. However, there is a bright spot: the new breed of convertible Chromebooks being released now. And they run Android apps:</p>

<ul>
  <li><a href="https://www.wired.com/2016/09/chromebooks-totally-transform-laptop-design/">How Chromebooks Are About to Totally Transform Laptop Design</a></li>
  <li><a href="https://chromeunboxed.com/detachable-chromebooks-pixel-c-and-the-future-of-chrome-os/">Detachable Chromebooks, Pixel C And The Future Of Chrome OS</a></li>
  <li><a href="https://arstechnica.com/gadgets/2017/02/samsungs-chromebook-pro-a-thoughtful-marriage-of-android-and-chrome-os/">Samsung’s Chromebook Pro gives me hope in Chrome OS—thanks to Android’s help</a></li>
</ul>

<p>Chrome OS is another clean, legacy free, modern computing interface. With these new devices you get the combination of a full desktop browser and the ability to run all Android tablet software.</p>

<p>The Samsung Chromebook Pro/Plus mentioned above is definitely interesting. A high-res 12” screen and a digital pen which I see as something very promising for <a href="https://flowhub.io">visual programming</a> purposes.</p>

<p>However, given that I already have a great mechanical keyboard, I’d love a device that shipped without an attached keyboard. We’ll see what kind of devices get out later this year.</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a43a1e384de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a43a1e384de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a43a1e384de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a43a1e384de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Fri, 10 Feb 2017 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a43a1e384de9a11e7894e07d57c4b55bb55bb</guid>
        </item>
        <item>
            <title>Process API for NoFlo components</title>
            <link>http://bergie.iki.fi/blog/noflo-process-api/</link>
            <description><![CDATA[
<p>It has been a while that I’ve written about <a href="http://bergie.iki.fi/blog/category/fbp">flow-based programming</a> — but now that I’m putting most of my time to <a href="https://flowhub.io">Flowhub</a> things are moving really quickly.</p>

<p>One example is the new component API in <a href="https://noflojs.org">NoFlo</a> that has been emerging over the last year or so.</p>

<p>Most of the work described here was done by <a href="https://github.com/trustmaster">Vladimir Sibirov</a> from <a href="https://thegrid.io">The Grid</a> team.</p>

<h2 id="introducing-the-process-api">Introducing the Process API</h2>

<p>NoFlo programs consist of graphs where different nodes are connected together. These nodes can themselves be graphs, or they can be components written in JavaScript.</p>

<p>A NoFlo component is simply a <a href="https://www.sitepoint.com/understanding-module-exports-exports-node-js/">JavaScript module</a> that provides a certain interface that allows NoFlo to run it. In the early days there was little convention on how to write components, but over time some conventions emerged, and with them helpers to build well-behaved components more easily.</p>

<p>Now with the upcoming NoFlo 0.8 release we’ve taken the best ideas from those helpers and rolled them back into the <code class="highlighter-rouge">noflo.Component</code> base class.</p>

<p>So, how does a component written using the Process API look like?</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Load the NoFlo interface</span>
<span class="kd">var</span> <span class="nx">noflo</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'noflo'</span><span class="p">);</span>
<span class="c1">// Also load any other dependencies you have</span>
<span class="kd">var</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'fs'</span><span class="p">);</span>

<span class="c1">// Implement the getComponent function that NoFlo's component loader</span>
<span class="c1">// uses to instantiate components to the program</span>
<span class="nx">exports</span><span class="p">.</span><span class="nx">getComponent</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
  <span class="c1">// Start by instantiating a component</span>
  <span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">noflo</span><span class="p">.</span><span class="nx">Component</span><span class="p">();</span>

  <span class="c1">// Provide some metadata, including icon for visual editors</span>
  <span class="nx">c</span><span class="p">.</span><span class="nx">description</span> <span class="o">=</span> <span class="s1">'Reads a file from the filesystem'</span><span class="p">;</span>
  <span class="nx">c</span><span class="p">.</span><span class="nx">icon</span> <span class="o">=</span> <span class="s1">'file'</span><span class="p">;</span>

  <span class="c1">// Declare the ports you want your component to have, including</span>
  <span class="c1">// their data types</span>
  <span class="nx">c</span><span class="p">.</span><span class="nx">inPorts</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">'in'</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">datatype</span><span class="p">:</span> <span class="s1">'string'</span>
  <span class="p">});</span>
  <span class="nx">c</span><span class="p">.</span><span class="nx">outPorts</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">'out'</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">datatype</span><span class="p">:</span> <span class="s1">'string'</span>
  <span class="p">});</span>
  <span class="nx">c</span><span class="p">.</span><span class="nx">outPorts</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">'error'</span><span class="p">,</span> <span class="p">{</span>
    <span class="na">datatype</span><span class="p">:</span> <span class="s1">'object'</span>
  <span class="p">});</span>

  <span class="c1">// Implement the processing function that gets called when the</span>
  <span class="c1">// inport buffers have packets available</span>
  <span class="nx">c</span><span class="p">.</span><span class="nx">process</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">output</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Precondition: check that the "in" port has a data packet.</span>
    <span class="c1">// Not necessary for single-inport components but added here</span>
    <span class="c1">// for the sake of demonstration</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">input</span><span class="p">.</span><span class="nx">hasData</span><span class="p">(</span><span class="s1">'in'</span><span class="p">))</span> <span class="p">{</span>
      <span class="k">return</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="c1">// Since the preconditions matched, we can read from the inport</span>
    <span class="c1">// buffer and start processing</span>
    <span class="kd">var</span> <span class="nx">filePath</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">getData</span><span class="p">(</span><span class="s1">'in'</span><span class="p">);</span>
    <span class="nx">fs</span><span class="p">.</span><span class="nx">readFile</span><span class="p">(</span><span class="nx">filePath</span><span class="p">,</span> <span class="s1">'utf-8'</span><span class="p">,</span> <span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="nx">contents</span><span class="p">)</span> <span class="p">{</span>
      <span class="c1">// In case of errors we can just pass the error to the "error"</span>
      <span class="c1">// outport</span>
      <span class="k">if</span> <span class="p">(</span><span class="nx">err</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">output</span><span class="p">.</span><span class="nx">done</span><span class="p">(</span><span class="nx">err</span><span class="p">);</span>
        <span class="k">return</span><span class="p">;</span>
      <span class="p">}</span>

      <span class="c1">// Send the file contents to the "out" port</span>
      <span class="nx">output</span><span class="p">.</span><span class="nx">send</span><span class="p">({</span>
        <span class="na">out</span><span class="p">:</span> <span class="nx">contents</span>
      <span class="p">});</span>
      <span class="c1">// Tell NoFlo we've finished processing</span>
      <span class="nx">output</span><span class="p">.</span><span class="nx">done</span><span class="p">();</span>
    <span class="p">});</span>
  <span class="p">});</span>

  <span class="c1">// Finally return to component to the loader</span>
  <span class="k">return</span> <span class="nx">c</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Most of this is still the same component API we’ve had for quite a while: instantiation, component metadata, port declarations. What is new is the <code class="highlighter-rouge">process</code> function and that is what we’ll focus on.</p>

<h3 id="when-is-process-called">When is <code class="highlighter-rouge">process</code> called?</h3>

<p>NoFlo components call their processing function whenever they’ve received packets to any of their regular inports.</p>

<p>In general any new information packets received by the component cause the <code class="highlighter-rouge">process</code> function to trigger. However, there are some exceptions:</p>

<ul>
  <li>Non-triggering ports don’t cause the function to be called</li>
  <li>Ports that have been set to forward brackets don’t cause the function to be called on bracket IPs, only on data</li>
</ul>

<h3 id="handling-preconditions">Handling preconditions</h3>

<p>When the processing function is called, the first job is to determine if the component has received enough data to act. These “<a href="http://ptolemy.eecs.berkeley.edu/papers/97/dataflow/">firing rules</a>” can be used for checking things like:</p>

<ul>
  <li>When having multiple inports, do all of them contain data packets?</li>
  <li>If multiple input packets are to be processed together, are all of them available?</li>
  <li>If receiving a <a href="http://jpaulmorrison.com/fbp/substrs.shtml">stream of packets</a> is the complete stream available?</li>
  <li>Any input synchronization needs in general</li>
</ul>

<p>The NoFlo component input handler provides methods for checking the contents of the input buffer. Each of these return a boolean if the conditions are matched:</p>

<ul>
  <li><code class="highlighter-rouge">input.has('portname')</code> whether an input buffer contains packets of any type</li>
  <li><code class="highlighter-rouge">input.hasData('portname')</code> whether an input buffer contains data packets</li>
  <li><code class="highlighter-rouge">input.hasStream('portname')</code> whether an input buffer contains at least one complete stream of packets</li>
</ul>

<p>For convenience, <code class="highlighter-rouge">has</code> and <code class="highlighter-rouge">hasData</code> can be used to check multiple ports at the same time. For example:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Fail precondition check unless both inports have a data packet</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">input</span><span class="p">.</span><span class="nx">hasData</span><span class="p">(</span><span class="s1">'in1'</span><span class="p">,</span> <span class="s1">'in2'</span><span class="p">))</span> <span class="k">return</span><span class="p">;</span>
</code></pre></div></div>

<p>For more complex checking it is also possible to pass a validation function to the <code class="highlighter-rouge">has</code> method. This function will get called for each information packet in the port(s) buffer:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// We want to process only when color is green</span>
<span class="kd">var</span> <span class="nx">validator</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">packet</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="nx">packet</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">color</span> <span class="o">===</span> <span class="s1">'green'</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// Run all packets in in1 and in2 through the validator to</span>
<span class="c1">// check that our firing conditions are met</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">input</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="s1">'in1'</span><span class="p">,</span> <span class="s1">'in2'</span><span class="p">,</span> <span class="nx">validator</span><span class="p">))</span> <span class="k">return</span><span class="p">;</span>
</code></pre></div></div>

<p>The firing rules should be checked in the beginning of the processing function before we start actually reading packets from the buffer. At that stage you can simply finish the run with a <code class="highlighter-rouge">return</code>.</p>

<h3 id="processing-packets">Processing packets</h3>

<p>Once your preconditions have been met, it is time to read packets from the buffers and start doing work with them.</p>

<p>For reading packets there are equivalent <code class="highlighter-rouge">get</code> functions to the <code class="highlighter-rouge">has</code> functions used above:</p>

<ul>
  <li><code class="highlighter-rouge">input.get('portname')</code> read the first packet from the port’s buffer</li>
  <li><code class="highlighter-rouge">input.getData('portname')</code> read the first data packet, discarding preceding bracket IPs if any</li>
  <li><code class="highlighter-rouge">input.getStream('portname')</code> read a whole stream of packets from the port’s buffer</li>
</ul>

<p>For <code class="highlighter-rouge">get</code> and <code class="highlighter-rouge">getStream</code> you receive whole <a href="https://noflojs.org/api/IP/">IP objects</a>. For convenience, <code class="highlighter-rouge">getData</code> returns just the data payload of the data packet.</p>

<p>When you have read the packets you want to work with, the next step is to do whatever your component is supposed to do. Do some simple data processing, call some remote API function, or whatever. NoFlo doesn’t really care whether this is done synchronously or asynchronously.</p>

<p><strong>Note:</strong> once you read packets from an inport, the component activates. After this it is necessary to finish the process by calling <code class="highlighter-rouge">output.done()</code> when you’re done.</p>

<h3 id="sending-packets">Sending packets</h3>

<p>While the component is active, it can send packets to any number of outports using the <code class="highlighter-rouge">output.send</code> method. This method accepts a map of port names and information packets.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">output</span><span class="p">.</span><span class="nx">send</span><span class="p">({</span>
  <span class="na">out1</span><span class="p">:</span> <span class="k">new</span> <span class="nx">noflo</span><span class="p">.</span><span class="nx">IP</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="s2">"some data"</span><span class="p">),</span>
  <span class="na">out2</span><span class="p">:</span> <span class="k">new</span> <span class="nx">noflo</span><span class="p">.</span><span class="nx">IP</span><span class="p">(</span><span class="s1">'data'</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>
<span class="p">});</span>
</code></pre></div></div>

<p>For data packets you can also just send the data as-is, and NoFlo will wrap it to an information packet.</p>

<p>Once you’ve finished processing, simply call <code class="highlighter-rouge">output.done()</code> to deactivate the component. There is also a convenience method that is a combination of <code class="highlighter-rouge">send</code> and <code class="highlighter-rouge">done</code>. This is useful for simple components:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">c</span><span class="p">.</span><span class="nx">process</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">output</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">getData</span><span class="p">(</span><span class="s1">'in'</span><span class="p">);</span>
  <span class="c1">// We just add one to the number we received and send it out</span>
  <span class="nx">output</span><span class="p">.</span><span class="nx">sendDone</span><span class="p">({</span>
    <span class="na">out</span><span class="p">:</span> <span class="nx">data</span> <span class="o">+</span> <span class="mi">1</span>
  <span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>

<p>In normal situations there packets are transmitted immediately. However, when working on individual packets that are part of a stream, NoFlo components keep an output buffer to ensure that packets from the stream are transmitted in original order.</p>

<h2 id="component-lifecycle">Component lifecycle</h2>

<p>In addition to making input processing easier, the other big aspect of the Process API is to help formalize NoFlo’s component and program lifecycle.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/a17b8582-fc33-11e5-9826-a722b90913ce.png" alt="NoFlo program lifecycle" /></p>

<p>The component lifecycle is quite similar to the program lifecycle shown above. There are three states:</p>

<ul>
  <li>Initialized: the component has been instantiated in a NoFlo graph</li>
  <li>Activated: the component has read some data from inport buffers and is processing it</li>
  <li>Deactivated: all processing has finished</li>
</ul>

<p>Once all components in a NoFlo network have deactivated, the whole program is finished.</p>

<p>Components are only allowed to do work and send packets when they’re activated. They shouldn’t do any work before receiving input packets, and should not send anything after deactivating.</p>

<h3 id="generator-components">Generator components</h3>

<p>Regular NoFlo components only send data associated with input packets they’ve received. One exception is generators, a class of components that can send packets whenever something happens.</p>

<p>Some examples of generators include:</p>

<ul>
  <li>Network servers that listen to requests</li>
  <li>Components that wait for user input like mouse clicks or text entry</li>
  <li>Timer loops</li>
</ul>

<p>The same rules of “only send when activated” apply also to generators. However, they can utilize the processing context to self-activate as needed:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">exports</span><span class="p">.</span><span class="nx">getComponent</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
 <span class="kd">var</span> <span class="nx">c</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">noflo</span><span class="p">.</span><span class="nx">Component</span><span class="p">();</span>
 <span class="nx">c</span><span class="p">.</span><span class="nx">inPorts</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">'start'</span><span class="p">,</span> <span class="p">{</span> <span class="na">datatype</span><span class="p">:</span> <span class="s1">'bang'</span> <span class="p">});</span>
 <span class="nx">c</span><span class="p">.</span><span class="nx">inPorts</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">'stop'</span><span class="p">,</span> <span class="p">{</span> <span class="na">datatype</span><span class="p">:</span> <span class="s1">'bang'</span> <span class="p">});</span>
 <span class="nx">c</span><span class="p">.</span><span class="nx">outPorts</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">'out'</span><span class="p">,</span> <span class="p">{</span> <span class="na">datatype</span><span class="p">:</span> <span class="s1">'bang'</span> <span class="p">});</span>
 <span class="c1">// Generators generally want to send data immediately and</span>
 <span class="c1">// not buffer</span>
 <span class="nx">c</span><span class="p">.</span><span class="nx">autoOrdering</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

 <span class="c1">// Helper function for clearing a running timer loop</span>
 <span class="kd">var</span> <span class="nx">cleanup</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
   <span class="c1">// Clear the timer</span>
   <span class="nx">clearInterval</span><span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">timer</span><span class="p">.</span><span class="nx">interval</span><span class="p">);</span>
   <span class="c1">// Then deactivate the long-running context</span>
   <span class="nx">c</span><span class="p">.</span><span class="nx">timer</span><span class="p">.</span><span class="nx">deactivate</span><span class="p">();</span>
   <span class="nx">c</span><span class="p">.</span><span class="nx">timer</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
 <span class="p">}</span>

 <span class="c1">// Receive the context together with input and output</span>
 <span class="nx">c</span><span class="p">.</span><span class="nx">process</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">input</span><span class="p">,</span> <span class="nx">output</span><span class="p">,</span> <span class="nx">context</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">hasData</span><span class="p">(</span><span class="s1">'start'</span><span class="p">))</span> <span class="p">{</span>
     <span class="c1">// We've received a packet to the "start" port</span>
     <span class="c1">// Stop the previous interval and deactivate it, if any</span>
     <span class="k">if</span> <span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">timer</span><span class="p">)</span> <span class="p">{</span>
       <span class="nx">cleanup</span><span class="p">();</span>
     <span class="p">}</span>
     <span class="c1">// Activate the context by reading the packet</span>
     <span class="nx">input</span><span class="p">.</span><span class="nx">getData</span><span class="p">(</span><span class="s1">'start'</span><span class="p">);</span>
     <span class="c1">// Set the activated context to component so it can</span>
     <span class="c1">// be deactivated from the outside</span>
     <span class="nx">c</span><span class="p">.</span><span class="nx">timer</span> <span class="o">=</span> <span class="nx">context</span>
     <span class="c1">// Start generating packets</span>
     <span class="nx">c</span><span class="p">.</span><span class="nx">timer</span><span class="p">.</span><span class="nx">interval</span> <span class="o">=</span> <span class="nx">setInterval</span><span class="p">(</span><span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
       <span class="c1">// Send a packet</span>
       <span class="nx">output</span><span class="p">.</span><span class="nx">send</span><span class="p">({</span>
         <span class="na">out</span><span class="p">:</span> <span class="kc">true</span>
       <span class="p">});</span>
     <span class="p">},</span> <span class="mi">100</span><span class="p">);</span>
     <span class="c1">// Since we keep the generator running we don't</span>
     <span class="c1">// call done here</span>
   <span class="p">}</span>

   <span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">hasData</span><span class="p">(</span><span class="s1">'stop'</span><span class="p">))</span> <span class="p">{</span>
     <span class="c1">// We've received a packet to the "stop" port</span>
     <span class="nx">input</span><span class="p">.</span><span class="nx">getData</span><span class="p">(</span><span class="s1">'stop'</span><span class="p">);</span>
     <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">c</span><span class="p">.</span><span class="nx">timer</span><span class="p">)</span> <span class="p">{</span>
       <span class="c1">// No timers running, we can just finish here</span>
       <span class="nx">output</span><span class="p">.</span><span class="nx">done</span><span class="p">();</span>
       <span class="k">return</span><span class="p">;</span>
     <span class="p">}</span>
     <span class="c1">// Stop the interval and deactivate</span>
     <span class="nx">cleanup</span><span class="p">();</span>
     <span class="c1">// Also call done for this one</span>
     <span class="nx">output</span><span class="p">.</span><span class="nx">done</span><span class="p">();</span>
   <span class="p">}</span>
 <span class="p">});</span>

 <span class="c1">// We also may need to clear the timer at network shutdown</span>
 <span class="nx">c</span><span class="p">.</span><span class="nx">tearDown</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">if</span> <span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">timer</span><span class="p">)</span> <span class="p">{</span>
     <span class="c1">// Stop the interval and deactivate</span>
     <span class="nx">cleanup</span><span class="p">();</span>
   <span class="p">}</span>
   <span class="nx">c</span><span class="p">.</span><span class="nx">emit</span><span class="p">(</span><span class="s1">'end'</span><span class="p">);</span>
   <span class="nx">c</span><span class="p">.</span><span class="nx">started</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
   <span class="nx">callback</span><span class="p">();</span>
 <span class="p">}</span>

 <span class="k">return</span> <span class="nx">c</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="time-to-prepare">Time to prepare</h2>

<p>NoFlo 0.7 included a preview version of the Process API. However, last week during the <a href="https://events.ccc.de/congress/2016/wiki/Main_Page">33C3</a> conference we finished some tricky bits related to process lifecycle and automatic bracket forwarding that make it more useful for real-life NoFlo applications.</p>

<p>These improvements will land in NoFlo 0.8, due out soon.</p>

<p>So, if you’re maintaining a NoFlo application, now is a good time to give the <a href="https://github.com/noflo/noflo">git version</a> a spin and look at porting your components to the new API. Make sure to report any issues you encounter!</p>

<p>We’re currently migrating all the <a href="https://www.npmjs.com/browse/keyword/noflo">hundred-plus NoFlo open source modules</a> to latest build and testing process so that they can be easily updated to the new APIs when they land.</p>
<span class="net_nemein_favourites">1 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e6d38ebfa2608ed38e11e6b78d03e3d20a42c042c0&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e6d38ebfa2608ed38e11e6b78d03e3d20a42c042c0/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e6d38ebfa2608ed38e11e6b78d03e3d20a42c042c0&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e6d38ebfa2608ed38e11e6b78d03e3d20a42c042c0/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 05 Jan 2017 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e6d38ebfa2608ed38e11e6b78d03e3d20a42c042c0</guid>
        </item>
        <item>
            <title>Full-Stack Flow-Based Programming</title>
            <link>http://bergie.iki.fi/blog/full-stack-fbp/</link>
            <description><![CDATA[
<p>The idea of <a href="http://coding.smashingmagazine.com/2013/11/21/introduction-to-full-stack-javascript/">Full-Stack Development</a> is quite popular at the moment — building things that run both the browser and the server side of web development, usually utilizing similar languages and frameworks.</p>

<p>With Flow-Based Programming and the emerging <a href="http://flowhub.io/">Flowhub</a> ecosystem, we can take this even further. Thanks to the <a href="http://noflojs.org/documentation/protocol/">FBP network protocol</a> we can build and monitor graphs spanning multiple devices and flow-based environments.</p>

<p><a href="http://jonnor.com/">Jon Nordby</a> gave a <a href="https://fosdem.org/2014/schedule/event/deviot02/">Flow-Based Programming talk in FOSDEM</a> Internet of Things track last weekend. His demo was running a FBP network comprising of three different environments that talk together. You can <a href="http://mirrors.dotsrc.org/fosdem/2014/AW1121/Sunday/Flowbased_programming_for_heterogeneous_systems.webm">find the talk online</a>.</p>

<video controls="" src="http://mirrors.dotsrc.org/fosdem/2014/AW1121/Sunday/Flowbased_programming_for_heterogeneous_systems.webm"></video>

<p>Here are some screenshots of the different graphs.</p>

<p><a href="http://microflo.org/">MicroFlo</a> running on an Arduino Microcontroller and monitoring a temperature sensor:</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/fullstack-microcontroller.png"><img src="https://d2vqpl3tx84ay5.cloudfront.net/fullstack-microcontroller-small.png" alt="MicroFlo on Arduino" /></a></p>

<p><a href="http://noflojs.org/">NoFlo</a> running on Node.js and communicating with the Arduino over a serial port:</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/fullstack-server-embedded.png"><img src="https://d2vqpl3tx84ay5.cloudfront.net/fullstack-server-embedded-small.png" alt="NoFlo on Node.js" /></a></p>

<p>NoFlo running in browser and communicating with the Node.js process over WebSockets:</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/fullstack-browser.png"><img src="https://d2vqpl3tx84ay5.cloudfront.net/fullstack-browser-small.png" alt="NoFlo on browser" /></a></p>

<p><em>(click to see the full-size picture)</em></p>

<h2 id="taking-this-further">Taking this further</h2>

<p>While this setup already works, as you can see the three graphs are still treated separately. The next obvious step will be to utilize the <a href="http://noflojs.org/">subgraph features</a> of NoFlo UI and allow different nodes of a graph represent different runtime environments.</p>

<p>This way you could introspect the data passing through all the wires in a single UI window, and “zoom in” to see each individual part of the system.</p>

<p>The FBP ecosystem is growing all the time, with different runtimes popping up for different languages and use cases. While NoFlo’s JavaScript focus makes it part of the <a href="http://bergie.iki.fi/blog/the_universal_runtime/">Universal Runtime</a>, there are many valid scenarios where other runtimes would be useful, especially on mobile, embedded, and desktop.</p>

<h2 id="work-to-be-done">Work to be done</h2>

<p>Interoperability between them is an area we should focus on. The <a href="http://noflojs.org/documentation/protocol/">network protocol</a> needs more scrutiny to ensure all scenarios are covered, and more of the FBP/dataflow systems need to integrate it.</p>

<p>Some steps are already being taken in this direction. After Jon’s session in FOSDEM we had a nice meetup discussing better integration between MicroFlo on microcontrollers, NoFlo on browser and server, and <a href="https://github.com/djdeath">Lionel Landwerlin’s</a> work on porting <a href="http://bergie.iki.fi/blog/noflo-and-gnome/">NoFlo to the GNOME desktop</a>.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/fullstack-meetup.jpg" alt="Full-stack FBP discussions at FOSDEM 2014" /></p>

<p>If you’re interested in collaborating, please <a href="http://noflojs.org/support/">get in touch</a>!</p>

<p><em>Photo by <a href="http://www.flickr.com/photos/forresto/12268512046/">Forrest Oliphant</a>.</em></p>
<span class="net_nemein_favourites">2 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e38f26d1bded2e8f2611e3b56f7dfae789b62cb62c&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e38f26d1bded2e8f2611e3b56f7dfae789b62cb62c/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e38f26d1bded2e8f2611e3b56f7dfae789b62cb62c&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e38f26d1bded2e8f2611e3b56f7dfae789b62cb62c/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 06 Feb 2014 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e38f26d1bded2e8f2611e3b56f7dfae789b62cb62c</guid>
        </item>
        <item>
            <title>Flowhub</title>
            <link>http://bergie.iki.fi/blog/flowhub/</link>
            <description><![CDATA[
<p>We just opened the <a href="http://flowhub.io/">Flowhub</a> website for pre-orders. Flowhub is the collaborative development environment for <a href="http://noflojs.org/">NoFlo</a> and other flow-based programming systems.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/flowhub-small.png" alt="Flowhub" /></p>

<p>Once it launches for general use, Flowhub is the fruition of the project initiated by our successful <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">NoFlo Development Environment</a> Kickstarter from last August.</p>

<p>Flowhub will provide a development environment for your flow-based programs, allowing you to collaborate and build things inside the same interface whether you’re targeting the client-side or the server-side of the web world. And thanks to the efforts on <a href="https://github.com/noflo/noflo/issues/107">creating a standard protocol</a> for flow-based runtimes, Flowhub will be able to work with other environments as well. To get a glimpse of this potential, take a look at Jon Nordby’s work on <a href="http://www.jonnor.com/2013/11/microflo-0-2-0-visual-arduino-programming/">Arduino programming with NoFlo UI</a> and what Lionel Landwerlin is doing with NoFlo in the <a href="http://bergie.iki.fi/blog/noflo-and-gnome/">Linux desktop development world</a>.</p>

<p>This is the main reason why we went with a more generic name for the new service. <em>Flowhub</em> aims to be the central hub for any flow-based development, not just the <a href="http://bergie.iki.fi/blog/the_universal_runtime/">JavaScript-centric world</a> where my NoFlo runtime is focused. Our Kickstarter sparked a lot of interest in flow-based programming in general, as evidenced by the various new FBP runtimes, and the <a href="http://www.kickstarter.com/projects/1712125778/dataflow-and-reactive-programming-systems">upcoming book</a> on the subject.</p>

<p>While NoFlo is and will remain our main focus, we should embrace the different ideas and different projects out there. One of the key points of FBP is everything can be modeled as a black box with input and output ports. With this level of abstraction, and a standard communications protocol, the different systems will be able to work together. Flowhub can be the central point for enabling that.</p>

<h2 id="collaboration-as-a-service">Collaboration as a service</h2>

<p>NoFlo is open source, and so is the <a href="https://github.com/noflo/noflo-ui">development environment</a> we’re building for it. For developing things on your own, this is pretty much all you’ll need, especially if you’re willing to set up things like the NoFlo environment for Node.js yourself.</p>

<p>The role of Flowhub as a service is analogous to what GitHub provides for traditional software development. Anybody can serve git repositories and issue trackers on their own, but having a third party to take care of that gives a much simpler, smoother experience. And even more importantly, having a central point where multiple projects reside enables much better collaboration and discovery between teams and projects.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/flowhub-preorder-small.png" alt="Flowhub plans" /></p>

<p>This is the essence of what Flowhub will provide:</p>

<ul>
  <li>Hosted version of the NoFlo UI, able to communicate with multiple different FBP runtimes whether running on client or server</li>
  <li>Integration with GitHub’s version control and issue tracking capabilities</li>
  <li>Peer-to-peer environment for team collaboration based on <a href="http://www.webrtc.org/">WebRTC</a></li>
  <li>Hosted environment for running server-side NoFlo programs and their <a href="https://github.com/noflo/noflo-test">tests</a></li>
</ul>

<p>As promised in our Kickstarter, the service will open to the public in the early summer of 2014. Our <a href="http://noflojs.org/kickstarter/">Kickstarter backers</a> will gain an early access and have already service plans provided for them. With our <a href="http://flowhub.io/preorder/">Flowhub pre-order campaign</a>, those who missed the Kickstarter opportunity have still a way to get in with early adopter pricing.</p>

<h2 id="new-technologies-and-a-new-ui">New technologies and a new UI</h2>

<p>Like NoFlo itself, Flowhub is also an exploration of various new technologies. From the layout technologies and the use of <a href="http://www.w3.org/TR/components-intro/">Web Components</a>, and the flow-based payment processing infrastructure handling both <a href="http://bergie.iki.fi/blog/bitcoin-medium-of-exchange/">Bitcoin</a> and credit card transactions that we built in <a href="http://noflojs.org/">NoFlo</a> — there are many things being dogfooded on the service.</p>

<p>At this stage of the game there are sure to be some rough edges, but by the time Flowhub opens to the public there should’ve been enough time at both our end, and with web browsers to mature to the point where these things provide a smooth experience.</p>

<p>The user interface <a href="http://bergie.iki.fi/blog/noflo-update/">we showed in September</a>, and user-tested in the <a href="https://plus.google.com/events/cenb1vcbrv2k5tufkog73ped89k">NodeCopter NoFlo event</a> has since seen quite a lot of improvement based on what we’ve learned. The new version has been rebuilt ground-up with <a href="http://www.polymer-project.org/">Polymer</a> and <a href="http://noflojs.org/">NoFlo</a>, and is a lot more efficient and touch-friendly.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/flowhub-team-small.jpg" alt="Flowhub team testing the new UI" /></p>

<p>It is still not perfect, but having used it on various devices from small tablets through laptops to huge touch-screen PCs, I feel we’re definitely on the right track. Having a user interface where you can <em>see the connections and data flows of your software</em> in real time, and can <em>rewire any part</em> when needed is incredibly powerful. And once <a href="https://github.com/noflo/noflo-ui/issues/8">component editing</a> is working fully with the runtimes, I can’t really see myself wanting to go back to text-only development.</p>

<p>Here is a sneak peek (click to see a bigger version):</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui-photobooth.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui-photobooth-small.png" alt="New NoFlo UI in action" /></a></p>

<p><em>To see more of what we’re building, visit <a href="http://flowhub.io">flowhub.io</a>, play with the demo we have there, and make sure to watch the intro video. <a href="http://flowhub.io/preorder/">Preorder today</a> to help fund the hosted and open source version of Flowhub!</em></p>
<span class="net_nemein_favourites">2 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e36392ceb6b0bc639211e3b8efa9d59524a385a385&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e36392ceb6b0bc639211e3b8efa9d59524a385a385/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e36392ceb6b0bc639211e3b8efa9d59524a385a385&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e36392ceb6b0bc639211e3b8efa9d59524a385a385/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 12 Dec 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e36392ceb6b0bc639211e3b8efa9d59524a385a385</guid>
        </item>
        <item>
            <title>An update from the NoFlo world</title>
            <link>http://bergie.iki.fi/blog/noflo-update/</link>
            <description><![CDATA[
<p>Wow, September was a busy month. As you probably know, our <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">NoFlo Development Environment Kickstarter</a> succeeded with 115% funding. Thanks everybody!</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-kickstarter-thank-you.png" alt="Thanks for supporting NoFlo!" /></p>

<p>Since then we’ve been busy hacking on the user interface and other parts of NoFlo to deliver the flow-based programming experience the community deserves. This post gives an overview on some of that.</p>

<h2 id="managing-your-graphs">Managing your graphs</h2>

<p>Here is how the NoFlo Development Environment looks like today, in this case editing the graph that runs a battery level instrument connected to an <a href="http://bergie.iki.fi/blog/noflo-ardrone/">AR.Drone</a>:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/battery-graph-small.png" alt="Editing a client-side graph" /></p>

<p>All the basics of graph editing are there. You can drag and drop to make connections between ports of the different nodes, and rearrange them. When dragging we emphasise the ports that are compatible with whatever you’re connecting. Ports that are not available or are of a wrong type fade out:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/connecting.png" alt="Connecting two number ports" /></p>

<p>When you click a node you can see what component is running it, as well as edit possible <a href="http://www.jpaulmorrison.com/fbp/reusparm.shtml">Initial Information Packets</a> to be sent to it when the graph is started:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/node-inspector.png" alt="Inspecting a node" /></p>

<p>Clicking a connection gives you a card showing the data passing through that connection in real time:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/edge-inspector.png" alt="Inspecting an edge" /></p>

<p>Adding new nodes can be done by dragging a component out from the library:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/library.png" alt="Adding a new node" /></p>

<p>As is usual with modern software, there is no <em>save button</em> anywhere. Instead, we constantly store the changes to your browser’s LocalStorage ensuring that you <a href="http://bergie.iki.fi/blog/never-lose-content/">never lose content</a>. Eventually we’ll give you tools to commit the changes up to version control too.</p>

<h2 id="keyboard-control">Keyboard control</h2>

<p>While the NoFlo Development Environment should work very nicely with tablets and other touchscreen devices, it is likely that many developers will still be using devices with a physical keyboard. For this, we’re adding a bunch of <a href="https://github.com/meemoo/dataflow/issues/57">keyboard shortcuts</a> for faster graph editing.</p>

<p>The UI also features a search box where you can query things inside your graphs and the available components:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/search.png" alt="Searching the graph" /></p>

<p>In addition to textual queries, the search widget allows written commands, a feature that was inspired by <a href="https://wiki.mozilla.org/Labs/Ubiquity/Latest_Ubiquity_User_Tutorial">Mozilla Ubiquity</a>:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/search-commands.png" alt="Removing a node via command-line" /></p>

<p>On compatible browsers you can even edit your graph by talking, though at times the results may be more funny than useful:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/speech-recognition.png" alt="Speaking to NoFlo" /></p>

<h2 id="talking-to-different-fbp-runtimes">Talking to different FBP runtimes</h2>

<p><a href="http://noflojs.org">NoFlo</a> works on both Node.js and web browsers. Since a big part of the development environment is being able to inspect and modify live NoFlo graphs, we needed a way for the UI to talk to both environments. To make this easier, we defined a <a href="https://github.com/noflo/noflo/issues/107">network protocol for FBP runtimes</a>.</p>

<p>This protocol allows transmitting graph and component information across the network, as well as controlling the execution of FBP graphs and seeing what happens with them. With client-side graphs we isolate the runtime to an iframe, and with server-side we talk over WebSockets.</p>

<p>The runtime protocol allows us to start and stop network execution. For client-side graphs you even get a nice preview:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/clock-demo-preview-small.png" alt="Clock demo in NoFlo" /></p>

<p>Here is a simple server-side graph that just reads a file and outputs its contents. You can see how we even get the output of <code class="highlighter-rouge">console.log</code> back to the UI:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/node-console-output-small.png" alt="Node.js console output in NoFlo UI" /></p>

<p>Error handling is also provided. You get notifications on any errors that happen with your graphs, as well as things like lost connection to a server-side NoFlo runtime:</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/lost-connection-small.png" alt="Lost connection to a runtime" /></p>

<p>An interesting side effect of having a <a href="https://github.com/noflo/noflo/issues/107">network protocol</a> is that it doesn’t really matter to the UI whether it talks to NoFlo or to any other FBP system, as long as they are able to talk the same protocol. Various flow-based programming environments for other languages have expressed interest in our development environment, and by providing the protocol they can do this easily.</p>

<p>The first FBP environment to get there was Jon Nordby’s <a href="https://github.com/jonnor/microflo">MicroFlo</a>, a flow-based programming system for microcontrollers like <a href="http://arduino.cc/">Arduino</a>. Imagine controlling hardware in a flow-based manner! Jon <a href="http://www.jonnor.com/2013/09/microflo-0-1-0-and-an-arduino-powered-fridge/">already programmed his fridge this way</a>.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui/microflo-tweet.png" alt="Jon's tweet about the UI working with MicroFlo" /></p>

<p><a href="https://github.com/trustmaster/goflow#readme">GoFlow</a>, the flow-based library for the Go programming language is also <a href="https://github.com/trustmaster/goflow/issues/12">planning to add support</a>, as is the <a href="https://hackerfleet.org/dev/wiki/cape">cape</a> environment for Python.</p>

<h2 id="relevant-repositories">Relevant repositories</h2>

<p>NoFlo is open source, and so is the development environment we’re building. If you want to stay up to date on our progress, these are the GitHub repositories to follow:</p>

<ul>
  <li><a href="https://github.com/noflo/noflo-ui">noflo/noflo-ui</a> - the client-side development environment</li>
  <li><a href="https://github.com/meemoo/dataflow">meemoo/dataflow</a> - our graph editing widget</li>
  <li><a href="https://github.com/noflo/noflo-ui-server">noflo/noflo-ui-server</a> - Node.js server for serving the UI and running server-side NoFlo processes</li>
</ul>

<h2 id="trying-it-out">Trying it out</h2>

<p>If you just want to play with some client-side graphs, the easiest way to use the NoFlo Development Environment is to <a href="http://noflojs.org/noflo-ui">open it in your browser</a>. Try tweaking <a href="http://noflojs.org/noflo-ui/#example/6699161">the clock demo</a> for instance.</p>

<p>This is a snapshot of the UI that we update every now and then. For the cutting edge version, just install from git and build locally. However, we’re actively changing things all the time at this point, so the UI might be incomplete or some things might not work at times.</p>

<h2 id="what-happens-next">What happens next?</h2>

<p>Right now our main areas of focus are:</p>

<ul>
  <li>Better touch interaction (<a href="https://github.com/meemoo/dataflow/issues/53">ticket</a>)</li>
  <li>Persistent cards for keeping inspectors you need open all the time (<a href="https://github.com/meemoo/dataflow/issues/55">ticket</a>)</li>
  <li>Managing whole NoFlo projects instead of single, isolated graphs (<a href="https://github.com/noflo/noflo-ui/issues/17">ticket</a>)</li>
</ul>

<p>The last one is quite important, as that will open the way for implementing highly useful features like <a href="https://github.com/noflo/noflo-ui/issues/8">component editing in the UI</a>, subgraph creation, and integration with version control services.</p>

<p>On technical level, big part right now is move to graphs and <a href="http://www.polymer-project.org/">Web Components</a>. The NoFlo user interface is based on the graph editing tools we inherited from Forrest’s <a href="http://meemoo.org/">Meemoo</a> project, but we’re moving more and more of the UI logic itself into graphs managed and run by NoFlo. It is kind of cool to start getting to the stage where we can use the tool to build itself!</p>
<span class="net_nemein_favourites">2 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e32d082af8da2e2d0811e3a25a01d180295eb85eb8&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e32d082af8da2e2d0811e3a25a01d180295eb85eb8/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e32d082af8da2e2d0811e3a25a01d180295eb85eb8&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e32d082af8da2e2d0811e3a25a01d180295eb85eb8/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Fri, 04 Oct 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e32d082af8da2e2d0811e3a25a01d180295eb85eb8</guid>
        </item>
        <item>
            <title>Interview with J. Paul Morrison, the father of Flow-Based Programming</title>
            <link>http://bergie.iki.fi/blog/paul-morrison-interview/</link>
            <description><![CDATA[
<p><a href="http://en.wikipedia.org/wiki/John_Paul_Morrison">J. Paul Morrison</a> invented <a href="http://en.wikipedia.org/wiki/Flow-based_programming">Flow-Based Programming</a> while at IBM in 1969.</p>

<p>I ran into the concept <a href="http://bergie.iki.fi/blog/interview-noflo-origins/">in 2011</a> while trying to figure out a better way to create software. I read <a href="http://amzn.com/1451542321">his canonical book</a> on the subject, and decided to try and implement it in JavaScript. Thus, <a href="http://noflojs.org/">NoFlo</a> got started.</p>

<p>It has been an honor to have Paul as a mentor in the process. In late June 2013 we flew to Toronto to meet him. What resulted was quite a thorough code review of NoFlo’s FBP implementation, and a video interview. The <a href="https://vimeo.com/72238422">interview with Paul</a> is finally online. Enjoy!</p>

<iframe src="http://bergie.iki.fi//player.vimeo.com/video/72238422?color=ffffff" width="500" height="281" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>

<p>If you want to meet Paul in person, the next opportunity will be in the <a href="http://www.meetup.com/Toronto-GTA-Flow-Based-Programming-Meetup/">Toronto Flow-Based Programming meetup</a> on September 11th. On the same week we also have <a href="http://techup.ch/1209/webtuesday-noflo-flow-based-programming-for-javascript">my NoFlo talk in Zurich</a> on the 10th, and <a href="http://2013.jsconf.eu/">Forrest’s talk in Berlin</a> on the 14th.</p>

<p><em>In other news, the <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">NoFlo Kickstarter campaign</a> just hit 96%. Please help us get it funded so we can bring better flow-based tools to designers and programmers everywhere!</em></p>
<span class="net_nemein_favourites">3 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e316e673b1f74216e611e3a5d14bc4b84c1fad1fad&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e316e673b1f74216e611e3a5d14bc4b84c1fad1fad/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e316e673b1f74216e611e3a5d14bc4b84c1fad1fad&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e316e673b1f74216e611e3a5d14bc4b84c1fad1fad/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Fri, 06 Sep 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e316e673b1f74216e611e3a5d14bc4b84c1fad1fad</guid>
        </item>
        <item>
            <title>GeoClue rises again</title>
            <link>https://bergie.iki.fi/blog/geoclue2/</link>
            <description><![CDATA[
<p>Those that have been following my blog for a longer time know that I’ve been <a href="http://bergie.iki.fi/blog/category/geo/">talking a lot</a> about making the Linux <a href="http://bergie.iki.fi/blog/making_the_gnome_desktop_location-aware/">desktop</a> and <a href="http://bergie.iki.fi/blog/iphone-geoclue_and_making_mobile_devices_location-aware/">mobile</a> platforms location aware.</p>

<p>Thanks to the amazing advances in <a href="http://bergie.iki.fi/blog/mobile-first-web/">adoption of mobile platforms</a>, this dream has more or less become true, especially in the more widespread Apple and Android ecosystems. All these devices know where they are, and developers are coming up with different smart applications to utilize this information.</p>

<p>The free software world has been at risk of getting left behind. <a href="http://en.wikipedia.org/wiki/GeoClue">GeoClue</a>, the location framework designed for these environments was in a state of flux for a long time with very little happening to it. But now we have <a href="http://gitorious.org/geoclue2#more">GeoClue2</a>, a rewritten implementation of the original idea.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/geoclue-200.png" alt="GeoClue" /></p>

<p><a href="http://lwn.net/SubscriberLink/562141/d1e7180f05f40d60/">LWN has a good write-up</a>:</p>

<blockquote>
  <p>Zeeshan Ali spoke about GNOME’s geo-awareness, which is undergoing a rewrite. Geo-awareness consists of four major pieces, he said. The first is geolocation, or the “where am I?” question. The second is the opposite; the user wants to find a different location: a particular address, a nearby restaurant or gas station, or other points of interest. The third issue is routing, finding the best way to get between locations. Finally, there is the user interface topic: locations, points of interest, and routes all need to be presented to the user on a map.</p>
</blockquote>

<blockquote>
  <p>GeoClue2 can determine location from four different sources: coordinates from GPS devices (the most accurate), the location of nearby WiFi access points (which is accurate to just a few hundred meters), the location of 3G cellular towers (which are accurate only to a few kilometers), and IP addresses (which are accurate only down to the city level).</p>
</blockquote>

<p>A major shortcoming that the new service addresses is privacy:</p>

<blockquote>
  <p>GeoClue2 also offers better privacy controls; the previous version of the library would provide the current location to any application; with GeoClue2, GNOME will require the user to confirm location requests from each application.</p>
</blockquote>

<p>Kudos to <a href="http://www.linkedin.com/in/zeenix">Zeeshan</a> and the others involved for keeping the location-aware dream alive!</p>

<p><em>I haven’t personally been involved much in the free desktop world lately. This is mainly because I’ve been busy trying to change the worlds of <a href="http://createjs.org/">web publishing</a> and <a href="https://noflojs.org/">software development</a>, but also because I don’t really have a desktop at the moment. Instead, I do my work with <a href="http://bergie.iki.fi/blog/working-on-android/">an Android tablet</a> and a <a href="http://www.google.de/intl/en/chrome/devices/chromebook-pixel/">web browser with an attached keyboard</a>. But despite that, I hope this will be picked up not only by <a href="http://www.gnome.org/">GNOME</a>, but by the <a href="http://www.ubuntu.com/">other</a> <a href="https://sailfishos.org/">Linux</a> <a href="http://kde.org/">ecosystems</a> as well.</em></p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a4109c6e6de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a4109c6e6de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a4109c6e6de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a4109c6e6de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 08 Aug 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a4109c6e6de9a11e7894e07d57c4b55bb55bb</guid>
        </item>
        <item>
            <title>GeoClue rises again</title>
            <link>http://bergie.iki.fi/blog/geoclue2/</link>
            <description><![CDATA[
<p>Those that have been following my blog for a longer time know that I’ve been <a href="http://bergie.iki.fi/blog/category/geo/">talking a lot</a> about making the Linux <a href="http://bergie.iki.fi/blog/making_the_gnome_desktop_location-aware/">desktop</a> and <a href="http://bergie.iki.fi/blog/iphone-geoclue_and_making_mobile_devices_location-aware/">mobile</a> platforms location aware.</p>

<p>Thanks to the amazing advances in <a href="http://bergie.iki.fi/blog/mobile-first-web/">adoption of mobile platforms</a>, this dream has more or less become true, especially in the more widespread Apple and Android ecosystems. All these devices know where they are, and developers are coming up with different smart applications to utilize this information.</p>

<p>The free software world has been at risk of getting left behind. <a href="http://en.wikipedia.org/wiki/GeoClue">GeoClue</a>, the location framework designed for these environments was in a state of flux for a long time with very little happening to it. But now we have <a href="http://gitorious.org/geoclue2#more">GeoClue2</a>, a rewritten implementation of the original idea.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/geoclue-200.png" alt="GeoClue" /></p>

<p><a href="http://lwn.net/SubscriberLink/562141/d1e7180f05f40d60/">LWN has a good write-up</a>:</p>

<blockquote>
  <p>Zeeshan Ali spoke about GNOME’s geo-awareness, which is undergoing a rewrite. Geo-awareness consists of four major pieces, he said. The first is geolocation, or the “where am I?” question. The second is the opposite; the user wants to find a different location: a particular address, a nearby restaurant or gas station, or other points of interest. The third issue is routing, finding the best way to get between locations. Finally, there is the user interface topic: locations, points of interest, and routes all need to be presented to the user on a map.</p>
</blockquote>

<blockquote>
  <p>GeoClue2 can determine location from four different sources: coordinates from GPS devices (the most accurate), the location of nearby WiFi access points (which is accurate to just a few hundred meters), the location of 3G cellular towers (which are accurate only to a few kilometers), and IP addresses (which are accurate only down to the city level).</p>
</blockquote>

<p>A major shortcoming that the new service addresses is privacy:</p>

<blockquote>
  <p>GeoClue2 also offers better privacy controls; the previous version of the library would provide the current location to any application; with GeoClue2, GNOME will require the user to confirm location requests from each application.</p>
</blockquote>

<p>Kudos to <a href="http://www.linkedin.com/in/zeenix">Zeeshan</a> and the others involved for keeping the location-aware dream alive!</p>

<p><em>I haven’t personally been involved much in the free desktop world lately. This is mainly because I’ve been busy trying to change the worlds of <a href="http://createjs.org/">web publishing</a> and <a href="http://noflojs.org/">software development</a>, but also because I don’t really have a desktop at the moment. Instead, I do my work with <a href="http://bergie.iki.fi/blog/working-on-android/">an Android tablet</a> and a <a href="http://www.google.de/intl/en/chrome/devices/chromebook-pixel/">web browser with an attached keyboard</a>. But despite that, I hope this will be picked up not only by <a href="http://www.gnome.org/">GNOME</a>, but by the <a href="http://www.ubuntu.com/">other</a> <a href="https://sailfishos.org/">Linux</a> <a href="http://kde.org/">ecosystems</a> as well.</em></p>
<span class="net_nemein_favourites">2 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e3000adcd23676000a11e3808351591d7703de03de&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e3000adcd23676000a11e3808351591d7703de03de/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e3000adcd23676000a11e3808351591d7703de03de&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e3000adcd23676000a11e3808351591d7703de03de/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 08 Aug 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e3000adcd23676000a11e3808351591d7703de03de</guid>
        </item>
        <item>
            <title>My interview on the origins of NoFlo</title>
            <link>http://bergie.iki.fi/blog/interview-noflo-origins/</link>
            <description><![CDATA[
<p><a href="https://vimeo.com/68285726">Here</a> is a video interview of me talking about the origins of <a href="http://noflojs.org/">NoFlo</a>, the flow-based programming environment for JavaScript:</p>

<iframe src="https://player.vimeo.com/video/68285726?title=0&amp;byline=0&amp;portrait=0" width="640" height="360" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>

<p>You’ve seen short pieces from this in the <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">NoFlo Kickstarter video</a>, but most of the material is new. This was shot when <a href="http://bergie.iki.fi/blog/noflo-two-years/">NoFlo turned two</a>, and so I’m obviously spending some time talking about where things came from.</p>

<p>The video should work well to support the <a href="http://bergie.iki.fi/blog/noflo-kickstarter-launch/">hacker’s perspective</a> of our funding campaign. Please <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">support us</a> and spread the word!</p>

<p><em>It is pretty amazing to think that since <a href="http://bergie.iki.fi/blog/noflo-kickstarter-launch/">my last post</a> on Friday, we’ve almost doubled the amount of contributions. Thanks to all the <strong>nearly 500 backers</strong> who have already helped us to change the world of programming!</em></p>
<span class="net_nemein_favourites">2 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e2fea46a9c353cfea411e2a48171f51af481a981a9&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e2fea46a9c353cfea411e2a48171f51af481a981a9/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e2fea46a9c353cfea411e2a48171f51af481a981a9&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e2fea46a9c353cfea411e2a48171f51af481a981a9/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Tue, 06 Aug 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e2fea46a9c353cfea411e2a48171f51af481a981a9</guid>
        </item>
        <item>
            <title>NoFlo Kickstarter, the hacker's perspective</title>
            <link>http://bergie.iki.fi/blog/noflo-kickstarter-launch/</link>
            <description><![CDATA[
<p>This has been a big week for <a href="http://noflojs.org/">NoFlo</a>, the flow-based programming environment for JavaScript. Yesterday we released <a href="https://github.com/noflo/noflo/releases/tag/0.4.0">NoFlo 0.4</a>, which added support for running flow-based programs in web browsers. And today we launched our <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">NoFlo Development Environment effort on Kickstarter</a>. Before continuing, make sure to watch <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">the video</a>!</p>

<iframe width="480" height="360" src="http:&#x2F;&#x2F;www.kickstarter.com&#x2F;projects&#x2F;noflo&#x2F;noflo-development-environment&#x2F;widget&#x2F;video.html" frameborder="0"> </iframe>

<p>This is our effort to bring visual and collaborative flow-based tools into the world of mainstream software development. Similar tools are already in use in many specialized industries from movie special effects to hardware simulation, but we programmers still have to <em>construct these complex maps of our software’s control flow</em> inside our brains based on their textual representation. With <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">your support</a>, we could change that!</p>

<p><strong>We’ve already reached a third of our goal on the first day. Clearly people see the need for these tools. Exciting times!</strong></p>

<p>The stories from <a href="http://techcrunch.com/2013/08/01/noflo-launches-kickstarter-campaign-to-provide-a-way-for-everyone-to-understand-and-visualize-code/">TechCrunch</a> and <a href="http://gigaom.com/2013/08/01/noflo-turns-to-kickstarter-to-expand-program-to-help-non-techies-read-code/">GigaOm</a> tell the story well for non-programmers. But based on the questions I’ve received today, I thought it would be good to clarify various points from a more programmer-centric point of view.</p>

<h2 id="hasnt-visual-programming-been-tried-before">Hasn’t visual programming been tried before?</h2>

<p>The story of visual programming tools started with the <a href="http://youtu.be/QQhVQ1UG6aM">GRaIL system</a> of the 60s, and has progressed to tools like <a href="http://www.ni.com/labview/">LabView</a> and <a href="http://puredata.info/">Pure Data</a>. So far none of these tools has reached mainstream acceptance outside of their (sometimes fanatic) industry niches.</p>

<p>This is partly because these tools were built originally with a particular problem domain in mind, and partly because of the user experience. Execution matters, as we’ve seen so many times in the tech industry. After all, there were tablets a lot before the iPads.</p>

<p>With <a href="http://www.kickstarter.com/profile/noflo">our team</a> I have the confidence that we have the necessary skills and vision to build something that is actually a pleasure to use, and that makes it truly easier to work with the control flow of your software than it is with the text editors.</p>

<p><em>This is not a rehash of UML</em>. UML is a diagram mapping out object-oriented constructs, often used for code generation. NoFlo graphs instead are only the <em>coordination layer</em> that manages the control flow of your software. The components are still handcrafted and unit-tested code that NoFlo merely wires together at runtime, following the edges specified in a <a href="http://noflojs.org/documentation/json/">JSON file</a>. No code generation here.</p>

<h2 id="why-map-out-the-control-flow">Why map out the control flow?</h2>

<p>All software is inherently a graph. Functions call other functions, sending data along. Signals are emitted and connections are made. But outside of some debugging tools we rarely see this in a visual format. Instead, when starting to work on a program you have to parse the code and build this map in your head.</p>

<p>This imposes a lot of cognitive load that tools like NoFlo could avoid. When you can see visually how things are connected, you can focus on the bigger picture and build the software you need in a more efficient way. This is what <a href="http://vimeo.com/71278954">Bret Victor talked about recently</a>.</p>

<iframe src="http://player.vimeo.com/video/71278954?title=0&amp;byline=0&amp;portrait=0" width="500" height="281" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>

<h2 id="what-is-the-role-for-code-then">What is the role for code, then?</h2>

<p>However, there still remains a role for text-based code. The actual components, the boxes in the graph, are still written out in JavaScript. But since they’re isolated from their surroundings until a NoFlo graph wires them together, each component can focus on accomplishing a single task well.</p>

<p>My original <a href="http://bergie.iki.fi/blog/inspiration-for-fbp-ui/">NoFlo UI prototype</a> already included the code editor for modifying and creating new components. By the principles of <a href="http://en.wikipedia.org/wiki/Test-driven_development">TDD</a>, each component is always edited alongside its unit tests, and the tests can be run at any point with a single click. We’re now bringing that back into the new UI:</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui-code.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/noflo-ui-code-small.jpg" alt="Editing code in the NoFlo UI" /></a></p>

<p>For those who don’t want this UI, NoFlo is still fully usable also without it. As a matter of fact, we don’t have a UI before the Kickstarter succeeds, and yet many companies are already building their applications with NoFlo. One way is by using the <a href="http://noflojs.org/documentation/fbp/"><code class="highlighter-rouge">.fbp</code> language</a>.</p>

<h2 id="why-now">Why now?</h2>

<p>Another reason why the <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">NoFlo development environment</a> may succeed where many others failed is that programming has changed.</p>

<p>We no longer target a single protocol — whether the Win32 API or HTTP — in our applications. Instead, we need to talk multiple protocols and with multiple devices at the same time. Even just dealing with both REST and WebSockets is difficult to many traditional programming environments.</p>

<p>The other big change is the usage of <a href="http://bergie.iki.fi/blog/internet-application-blueprint/">different web APIs</a> as part of your applications. Authentication, handling asynchronous requests and services that are sometimes down can be a pain.</p>

<p>NoFlo brings a <em>controlling layer</em> to your software that allows you to map out these scenarios and isolate the handling of each protocol or API into its own set of small, simple components.</p>

<h2 id="where-could-this-be-used">Where could this be used?</h2>

<p>Many of the nodal editing tools built in the past have been very domain-specific. However, <a href="http://en.wikipedia.org/wiki/Flow-based_programming">flow-based programming</a> is a general software development paradigm. NoFlo has already been used for a wide variety of tasks, including:</p>

<ul>
  <li>Business data extraction and reporting</li>
  <li>Automating billing workflows</li>
  <li>Receiving, routing, and sending text messages</li>
  <li>Static site generation</li>
  <li>Building server-side web applications</li>
</ul>

<p>Now that we <a href="https://github.com/noflo/noflo/releases/tag/0.4.0">added browser support</a> it will be possible to also build physics-based user interfaces with NoFlo. There should be some interesting examples of that coming up soon.</p>

<p>NoFlo being a general JavaScript library could in future enable us to coordinate the flows also in new kinds of places like desktop applications. There are <a href="http://www.gnome.org/">several</a> <a href="http://kde.org/">desktop</a> <a href="http://en.wikipedia.org/wiki/Windows_Runtime">environments</a> where JavaScript is a first-class citizen. Combining flow-based interactions with declarative UI definitions could be something very powerful!</p>

<p>Many of the giants of the software industry, like Google, Facebook, Microsoft, Adobe, and Mozilla are all working on improving the JavaScript development tools. It would be awesome to have their support for what we’re doing.</p>

<h2 id="how-about-open-source">How about open source?</h2>

<p>If you’re following this blog, you probably know that I feel strongly for software freedom. Everything I’ve done during my <a href="http://www.linkedin.com/in/bergie">professional career</a> has been possible only thanks to the open source community.</p>

<p><a href="http://noflojs.org/">NoFlo</a> and the UI we’re building are and will remain open source available under the <a href="https://en.wikipedia.org/wiki/MIT_License">MIT license</a>. As a matter of fact, the UI is designed to not only work with NoFlo, but also to be adaptable to work with other flow-based systems. I feel this is an area with a lot of potential for collaboration with the various functional and dataflow projects out there.</p>

<p>We will however be offering a hosted version of the software for a fee. The various <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">Kickstarter rewards</a> will give our backers an early and cheaper access to that.</p>

<p>But still, you’ll always be able to run the whole stack on your own infrastructure if you choose to do so.</p>

<h2 id="what-happens-next">What happens next?</h2>

<p>Our <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">Kickstarter campaign</a> has been up for less than a day, and we’re already <em>above 30%</em> of our goal. This makes me quite optimistic for the effort. But of course we won’t succeed without the help of the wider open source and JavaScript community!</p>

<p>There are still quite a lot of days left in the campaign. Tonight I’ll be flying back to Europe, and then we’ll focus on the next steps.</p>

<p>One important area of attention is publishing more demos and examples of NoFlo in real-world use. I hope by early next week we’ll be able to show a few applications running on both browser and Node.js. I will also publish our flow-based port of the <a href="http://jekyllrb.com/">Jekyll static site generator</a>. These should help people getting started with this style of programming.</p>

<p>We also have quite a lot of content lined up and waiting for editing. Something of interest to everybody working with flow-based or functional programming will be the long cut of the interview we made with <a href="http://en.wikipedia.org/wiki/John_Paul_Morrison">J. Paul Morrison</a>, the father of FBP. My hope is that video will be live by the end of the next week.</p>

<p>If you’re interested in the developments, make sure to follow NoFlo on <a href="https://twitter.com/noflo">Twitter</a>, <a href="https://www.facebook.com/noflo">Facebook</a>, or <a href="https://plus.google.com/u/0/112372998187205178398">Google+</a>. If you back <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">our campaign</a>, you’ll also receive the updates via Kickstarter.</p>

<p>Thanks everybody for helping to make this possible! Keep spreading the world and giving <a href="http://www.kickstarter.com/projects/noflo/noflo-development-environment">your support</a>!</p>
<span class="net_nemein_favourites">2 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e2fb19197a4c7cfb1911e2a307750bd098a835a835&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e2fb19197a4c7cfb1911e2a307750bd098a835a835/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e2fb19197a4c7cfb1911e2a307750bd098a835a835&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e2fb19197a4c7cfb1911e2a307750bd098a835a835/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Thu, 01 Aug 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e2fb19197a4c7cfb1911e2a307750bd098a835a835</guid>
        </item>
        <item>
            <title>Leap Motion and the virtual interfaces</title>
            <link>https://bergie.iki.fi/blog/leap-motion-virtual-interfaces/</link>
            <description><![CDATA[
<p>The eagerly waited <a href="https://www.leapmotion.com/">Leap Motion</a> controller is now out, and <a href="http://arstechnica.com/gadgets/2013/07/hands-on-with-the-leap-motion-controller-cool-but-frustrating-as-hell/">reviews</a> are pouring in. Most of them see the promise but find the current experience frustrating:</p>

<blockquote>
  <p>Here’s the thing: the Leap Motion is almost amazing. When using it to interact with my desktop and perform actions (clicking, dragging, scrolling), the experience is about 50 percent fluid intuition and 50 percent screaming frustration. There are moments, sometimes ten or fifteen seconds long, when everything magically clicks into place—the Leap doesn’t decide your hand is too far away or too close to be able to execute actions, and for a few seconds, boom, you’re scrolling, dragging, and clicking effortlessly. It feels totally natural. Then, almost capriciously, your gestures aren’t good enough any more and you spend ten more seconds trying to get a single click to register.</p>
</blockquote>

<p>I’ve had a Leap sensor as part of their <a href="https://www.leapmotion.com/developers">developer program</a> for a while now, and the description above feels quite accurate to both the Leap, and our <a href="http://bergie.iki.fi/blog/qt-air-cursor/">Kinect air cursor work</a>.</p>

<h2 id="lacking-interface-concepts">Lacking interface concepts</h2>

<p>The problem is that our current interface concepts are simply not suitable for this sort of interaction. There must be incredible things you can accomplish when <em>the computer can see your fingers or whole body in motion</em>. We just haven’t discovered them yet.</p>

<p>This is very similar to the situation we had for a long time with touchscreen devices. There have been tablets available since the 90s, but they didn’t take off until there was a <a href="http://en.wikipedia.org/wiki/IOS">new kind of OS</a> and <a href="http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html">new kind of UI guidelines</a> for this world. After all, your finger is not a mouse.</p>

<p>Once those guidelines were out there, and manufacturers built compelling enough all-touch devices, the market took off. I’ve said for a long time that <a href="http://bergie.iki.fi/blog/why_the_tablet_form_factor_is_winning/">the tablet form factor is winning</a>, an estimate validated by the <a href="http://www.asymco.com/2013/07/18/the-pc-calamity/">recent sales figures</a>. And yet, the new kind of tablets have only been available since <a href="http://bergie.iki.fi/blog/meego-diaspora/">2006</a> or <a href="http://en.wikipedia.org/wiki/IPad">2010</a> depending how you look. The big shift is only getting started.</p>

<p>Right now tablets are still mostly used for recreation and light data processing, as <a href="http://bergie.iki.fi/blog/tablet-productivity/">productivity applications and culture</a> always take a bit longer to adapt. We need to move beyond text as the main way of communicating ideas.</p>

<p>I’ve <a href="https://noflojs.org/">already taken a few steps</a> that way for us programmers.</p>

<h2 id="behind-the-glass">Behind the glass</h2>

<p>While there are many great user interfaces built on the touch paradigm, interacting with a featureless piece of glass lacks a lot of the haptic feedback we get from physical interfaces. The author <a href="https://en.wikipedia.org/wiki/Douglas_Adams">Douglas Adams</a> commented on this in <a href="http://en.wikipedia.org/wiki/The_Hitchhiker's_Guide_to_the_Galaxy">The Hitchhiker’s Guide to the Galaxy</a>already back in 1979:</p>

<blockquote>
  <p>A loud clatter of gunk music flooded through the Heart of Gold cabin as Zaphod searched the sub-etha radio wave bands for news of himself. The machine was rather difficult to operate. For years radios had been operated by means of pressing buttons and turning dials; then as the technology became more sophisticated the controls were made touch-sensitive–you merely had to brush the panels with your fingers; now all you had to do was wave your hand in the general direction of the components and hope. It saved a lot of muscular expenditure, of course, but meant that you had to sit infuriatingly still if you wanted to keep listening to the same program.</p>
</blockquote>

<blockquote>
  <p>Zaphod waved a hand and the channel switched again.</p>
</blockquote>

<p>(thanks to <a href="http://arstechnica.com/gadgets/2013/07/hands-on-with-the-leap-motion-controller-cool-but-frustrating-as-hell/?comments=1&amp;post=24987285#comment-24987285">Ars commenter Joannemullen</a>, I had forgotten about that quote!)</p>

<p>The book <a href="http://mitpress.mit.edu/books/invisible-computer">Invisible Computer</a> argues for building physical appliances for different computing purposes. I don’t see that happening anytime soon given the strong onward march of <a href="http://en.wikipedia.org/wiki/Ephemeralization">ephemeralization</a>, of moving everything to converged devices and increasingly capable software.</p>

<p>But even with software there would be so much more we could be doing.</p>

<h2 id="physical-interaction">Physical interaction</h2>

<p>The devices we carry around us are filled with different sensors which could provide new kinds of interaction concepts.</p>

<p>For example, on many Nokia phones you’ve been able to <a href="http://allaboutwindowsphone.com/flow/item/17791_Flip_to_silence_on_the_Nokia_L.php">mute the phone</a> by flipping it around. In 2001 I had an Ericsson phone which used the proximity sensor to <a href="http://www.ciol.com/ciol/news/123339/now-app-wave-hand-alarm">snooze the alarm</a> when you waved your hand over the phone.</p>

<p>iOS devices use the gesture of shaking the device to <a href="http://ipod.about.com/od/iphone3gs/qt/shake-to-shuffle-iphone.htm">shuffle a playlist</a> or <a href="http://ipod.about.com/od/iphonehowtos/qt/Shake-To-Undo-On-Iphone.htm">undo an action</a>. On many Android devices you can use NFC touches <a href="http://en.wikipedia.org/wiki/Android_Beam">to move data or interaction between devices</a>. Touch a screen to send a picture there, or touch a speaker to make your music play from there.</p>

<p>These are all great, natural gestures that allow us to interact with the device in a physical way, not with just with the virtual interfaces behind the glass.</p>

<p>Gestures like these should be more universally available, just like touch UI concepts like <a href="http://www.theverge.com/2013/5/21/4350826/twitter-pull-to-refresh-patent-innovators-patent-agreement-announced">pull to refresh</a>. When people trust a gesture to work consistently everywhere, it will be used a lot more, and users will be happier.</p>

<p>We are after all interating with physical devices we can not only touch, but also move around.</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a3e73e330de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a3e73e330de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a3e73e330de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a3e73e330de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Sat, 27 Jul 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a3e73e330de9a11e7894e07d57c4b55bb55bb</guid>
        </item>
        <item>
            <title>Leap Motion and the virtual interfaces</title>
            <link>http://bergie.iki.fi/blog/leap-motion-virtual-interfaces/</link>
            <description><![CDATA[
<p>The eagerly waited <a href="https://www.leapmotion.com/">Leap Motion</a> controller is now out, and <a href="http://arstechnica.com/gadgets/2013/07/hands-on-with-the-leap-motion-controller-cool-but-frustrating-as-hell/">reviews</a> are pouring in. Most of them see the promise but find the current experience frustrating:</p>

<blockquote>
  <p>Here’s the thing: the Leap Motion is almost amazing. When using it to interact with my desktop and perform actions (clicking, dragging, scrolling), the experience is about 50 percent fluid intuition and 50 percent screaming frustration. There are moments, sometimes ten or fifteen seconds long, when everything magically clicks into place—the Leap doesn’t decide your hand is too far away or too close to be able to execute actions, and for a few seconds, boom, you’re scrolling, dragging, and clicking effortlessly. It feels totally natural. Then, almost capriciously, your gestures aren’t good enough any more and you spend ten more seconds trying to get a single click to register.</p>
</blockquote>

<p>I’ve had a Leap sensor as part of their <a href="https://www.leapmotion.com/developers">developer program</a> for a while now, and the description above feels quite accurate to both the Leap, and our <a href="http://bergie.iki.fi/blog/qt-air-cursor/">Kinect air cursor work</a>.</p>

<h2 id="lacking-interface-concepts">Lacking interface concepts</h2>

<p>The problem is that our current interface concepts are simply not suitable for this sort of interaction. There must be incredible things you can accomplish when <em>the computer can see your fingers or whole body in motion</em>. We just haven’t discovered them yet.</p>

<p>This is very similar to the situation we had for a long time with touchscreen devices. There have been tablets available since the 90s, but they didn’t take off until there was a <a href="http://en.wikipedia.org/wiki/IOS">new kind of OS</a> and <a href="http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/Introduction/Introduction.html">new kind of UI guidelines</a> for this world. After all, your finger is not a mouse.</p>

<p>Once those guidelines were out there, and manufacturers built compelling enough all-touch devices, the market took off. I’ve said for a long time that <a href="http://bergie.iki.fi/blog/why_the_tablet_form_factor_is_winning/">the tablet form factor is winning</a>, an estimate validated by the <a href="http://www.asymco.com/2013/07/18/the-pc-calamity/">recent sales figures</a>. And yet, the new kind of tablets have only been available since <a href="http://bergie.iki.fi/blog/meego-diaspora/">2006</a> or <a href="http://en.wikipedia.org/wiki/IPad">2010</a> depending how you look. The big shift is only getting started.</p>

<p>Right now tablets are still mostly used for recreation and light data processing, as <a href="http://bergie.iki.fi/blog/tablet-productivity/">productivity applications and culture</a> always take a bit longer to adapt. We need to move beyond text as the main way of communicating ideas.</p>

<p>I’ve <a href="http://noflojs.org/">already taken a few steps</a> that way for us programmers.</p>

<h2 id="behind-the-glass">Behind the glass</h2>

<p>While there are many great user interfaces built on the touch paradigm, interacting with a featureless piece of glass lacks a lot of the haptic feedback we get from physical interfaces. The author <a href="https://en.wikipedia.org/wiki/Douglas_Adams">Douglas Adams</a> commented on this in <a href="http://en.wikipedia.org/wiki/The_Hitchhiker's_Guide_to_the_Galaxy">The Hitchhiker’s Guide to the Galaxy</a>already back in 1979:</p>

<blockquote>
  <p>A loud clatter of gunk music flooded through the Heart of Gold cabin as Zaphod searched the sub-etha radio wave bands for news of himself. The machine was rather difficult to operate. For years radios had been operated by means of pressing buttons and turning dials; then as the technology became more sophisticated the controls were made touch-sensitive–you merely had to brush the panels with your fingers; now all you had to do was wave your hand in the general direction of the components and hope. It saved a lot of muscular expenditure, of course, but meant that you had to sit infuriatingly still if you wanted to keep listening to the same program.</p>
</blockquote>

<blockquote>
  <p>Zaphod waved a hand and the channel switched again.</p>
</blockquote>

<p>(thanks to <a href="http://arstechnica.com/gadgets/2013/07/hands-on-with-the-leap-motion-controller-cool-but-frustrating-as-hell/?comments=1&amp;post=24987285#comment-24987285">Ars commenter Joannemullen</a>, I had forgotten about that quote!)</p>

<p>The book <a href="http://mitpress.mit.edu/books/invisible-computer">Invisible Computer</a> argues for building physical appliances for different computing purposes. I don’t see that happening anytime soon given the strong onward march of <a href="http://en.wikipedia.org/wiki/Ephemeralization">ephemeralization</a>, of moving everything to converged devices and increasingly capable software.</p>

<p>But even with software there would be so much more we could be doing.</p>

<h2 id="physical-interaction">Physical interaction</h2>

<p>The devices we carry around us are filled with different sensors which could provide new kinds of interaction concepts.</p>

<p>For example, on many Nokia phones you’ve been able to <a href="http://allaboutwindowsphone.com/flow/item/17791_Flip_to_silence_on_the_Nokia_L.php">mute the phone</a> by flipping it around. In 2001 I had an Ericsson phone which used the proximity sensor to <a href="http://www.ciol.com/ciol/news/123339/now-app-wave-hand-alarm">snooze the alarm</a> when you waved your hand over the phone.</p>

<p>iOS devices use the gesture of shaking the device to <a href="http://ipod.about.com/od/iphone3gs/qt/shake-to-shuffle-iphone.htm">shuffle a playlist</a> or <a href="http://ipod.about.com/od/iphonehowtos/qt/Shake-To-Undo-On-Iphone.htm">undo an action</a>. On many Android devices you can use NFC touches <a href="http://en.wikipedia.org/wiki/Android_Beam">to move data or interaction between devices</a>. Touch a screen to send a picture there, or touch a speaker to make your music play from there.</p>

<p>These are all great, natural gestures that allow us to interact with the device in a physical way, not with just with the virtual interfaces behind the glass.</p>

<p>Gestures like these should be more universally available, just like touch UI concepts like <a href="http://www.theverge.com/2013/5/21/4350826/twitter-pull-to-refresh-patent-innovators-patent-agreement-announced">pull to refresh</a>. When people trust a gesture to work consistently everywhere, it will be used a lot more, and users will be happier.</p>

<p>We are after all interating with physical devices we can not only touch, but also move around.</p>
<span class="net_nemein_favourites">1 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e2f7009f9743eaf70011e295d8ade3a0f807610761&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e2f7009f9743eaf70011e295d8ade3a0f807610761/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e2f7009f9743eaf70011e295d8ade3a0f807610761&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e2f7009f9743eaf70011e295d8ade3a0f807610761/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Sat, 27 Jul 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e2f7009f9743eaf70011e295d8ade3a0f807610761</guid>
        </item>
        <item>
            <title>The mobile-first Web</title>
            <link>https://bergie.iki.fi/blog/mobile-first-web/</link>
            <description><![CDATA[
<p>The growth of mobile web users is staggering. While <a href="http://bergie.iki.fi/blog/meego-diaspora/">some of us</a> have been browsing the web on mobile devices for nearly ten years, most of the world population is only now getting there.</p>

<p>The <a href="http://www.tuaw.com/2013/05/31/internet-trends-report-highlights-ipads-incredible-success-roo/">number of mobile web users</a> is already at 1.5 billion, which happens to be quite close to the <a href="http://www.internetworldstats.com/blog.htm">total number of Internet users</a> back in 2009.</p>

<p>And it is <a href="http://www.fiercemobileit.com/story/global-smartphone-market-growth-estimates-vary-among-research-firms/2013-06-03">growing rapidly</a>. In 2015 there will be an estimated <a href="http://finance.yahoo.com/news/number-smartphones-around-world-top-122000896.html">2 billion smartphone users</a> which is quite close to the total number of Internet users currently.</p>

<p>In the developed world, this is likely to be a mixture of tablets, smartphones, and traditional desktop computers, with most users having at least two different web-capable devices. In the developing world, <em>the smartphone is the computer</em>.</p>

<p>Considering these statistics, <em>it is insanity to design websites and services PC-first</em>, with mobile only as an afterthought.</p>

<h2 id="how-to-prepare">How to prepare</h2>

<p>Just some years ago, the mobile web was a slum. Instead of getting full-featured websites, many sent us out to poorly-built and featureless <a href="http://www.mobify.com/blog/6-reasons-mdot-websites-are-dead-ends/">m. sites</a>. Now more and more sites go with <a href="http://en.wikipedia.org/wiki/Responsive_web_design">responsive web design</a> that makes the site itself adapt to different screen sizes and resolutions.</p>

<p>But even with responsive design, it is easy to go overboard. Tools like <a href="http://jetpack.me/support/mobile-theme/">WordPress Jetpack</a> and <a href="http://jquerymobile.com/">jQuery Mobile</a> oversimplify the site itself by trying to make it look and feel like a native app. In the mobile-first world this is not the right way to go.</p>

<p>In <a href="http://blogs.hbr.org/cs/2013/05/the_rise_of_the_mobile-only_us.html">The Rise of the Mobile-Only User</a> content strategist Karen McGrane makes a valid point (emphasis added):</p>

<blockquote>
  <p>Mobile users should get the same content. It’s frustrating and confusing for them if you only give them a little bit of what you offer on your “real” website. If you try to guess which subset of your content the mobile user needs, you’re going to guess wrong. Deliver the same content as your desktop user sees. (<em>If you think some of your content doesn’t deserve to be on mobile, guess what — it doesn’t deserve to be on the desktop either. Get rid of it.</em>)</p>
</blockquote>

<h2 id="there-is-no-pixel-perfect">There is no pixel-perfect</h2>

<p>In this new world users will access your content or software using a wildly varying set of devices. And each of them has the reasonable expectation of being able to access the full experience and the full set of features you’re providing.</p>

<p>This changes web design substantially. Even in the old world of different PC browsers, <em>pixel perfect web design</em> was rarely that. With responsive design, it is <a href="http://blog.microsecommerce.com/index.php/uncategorized/responsive-design-and-the-demise-of-pixel-perfect/">even less so</a>.</p>

<p>Instead:</p>

<ul>
  <li>Think in <em>visual components instead of full pages</em>. The composition of a page out of these components can vary for different screen sizes</li>
  <li>Design the compositions always for at <em>three screen form factors</em>: a full-sized desktop or tablet screen, a smartphone screen, and the 7” tablet in between</li>
  <li>Make your <em>user interface elements big enough</em> to be used on inaccurate touch screens</li>
  <li><em>Never, ever require a plugin</em> to access some content or functionality</li>
</ul>

<p><a href="http://css-tricks.com/css-media-queries/">CSS Media Queries</a> make responding to different form factors quite easy. And besides that, they also make it easy to optimize for the <a href="http://developer.android.com/training/multiscreen/screendensities.html#TaskProvideAltBmp">different screen densities</a> we now have. This way your images will look sharp on anything the users have, from the “retina-class devices” to the lowest-specced Chinese smartphone, while requiring the user to only download the assets that their device can utilize.</p>

<p>The devices people use to access the services you provide will vary greatly not only in their display capabilities, but also in the ways you can do input. Some will have mice and physical keyboards, but an increasing amount will instead have a touchscreen. For these users, it is a big service to use the correct <a href="http://sixrevisions.com/html5/new-html5-form-input-types/">HTML5 input types</a> so that the on-screen keyboards and widgets can adapt to the content being entered.</p>

<h2 id="the-web-is-not-native">The web is not native</h2>

<p>The web is its own platform, and as such it is <em>foolish to try and mimic traditional desktop applications</em>. It will never feel quite right whatever you do.</p>

<p>It is a lot better to accept this and fully embrace the unique advantages of the web platform:</p>

<ul>
  <li><em>The web is an <a href="http://bergie.iki.fi/blog/the_universal_runtime/">universal runtime</a></em> that works on 100% of the computing devices your users have</li>
  <li><em>There are no gatekeepers</em> telling what you can publish, and <em>no middlemen</em> taking a cut of whatever you sell online</li>
  <li><em>The web is built out of URLs</em> that users can easily share with each other, and continue using when they switch devices</li>
  <li>URLs also allow <em>any application on the web to link to any screen or state of another application</em></li>
  <li>It is just as easy to <em>provide content as it is to provide functional applications</em> on the web</li>
</ul>

<p>Every major software company on the planet has their own web browser, and the competition between these is fierce. This will ensure that over time, the web will keep on getting better and faster. Compare this to traditional software platforms that can easily stagnate or get abandoned. Thanks to the standard protocols it also <em>allows you to use any technology of your choosing</em> for the server side of your software.</p>

<p>Paul Graham put it well in his <a href="http://paulgraham.com/road.html">The other road ahead</a> from 2001:</p>

<blockquote>
  <p>And you don’t have to know if you bet on Web-based applications. No one can break that without breaking browsing. The Web may not be the only way to deliver software, but it’s one that works now and will continue to work for a long time. Web-based applications are cheap to develop, and easy for even the smallest startup to deliver.</p>
</blockquote>

<h2 id="things-are-getting-better">Things are getting better</h2>

<p>As somebody who has been developing for the web for nearly <a href="http://press.web.cern.ch/press-releases/2013/04/cern-celebrates-20-years-free-open-web">twenty years</a> the rate the web developer experience keeps improving is sometimes dizzying.</p>

<p>We get used to some limitations in the stack, and then suddenly something comes along and removes that shortcoming. We’re still exploring the new kinds of designs and visual experiences technologies like Media Queries and <a href="http://en.wikipedia.org/wiki/WebGL">WebGL</a> make possible, just like it took years for the community to find best practices around things like AJAX.</p>

<p>And yet new amazing things keep pouring in. My personal favourite recently has been <a href="http://www.polymer-project.org/">Web Components</a> which gives a standard way to <em>provide reusable widgets on the web</em>, and to do things like <em>data binding and templating</em>. This alone will make a lot of the popular frameworks and libraries obsolete.</p>

<p>Just watch <a href="http://youtu.be/0g0oOOT86NY">this video</a> and see how much easier web development is becoming:</p>

<iframe width="500" height="281" src="https://www.youtube.com/embed/0g0oOOT86NY" frameborder="0" allowfullscreen=""></iframe>

<p>The current work on standardizing <a href="https://payswarm.com/">Web Payments</a> together with more grassroots efforts like <a href="http://bitcoin.org/en/">Bitcoin</a> promise to add better ways to do business on the web. This should remove the last big advantage of native applications in that they’re easier (but very expensive) to monetize via app stores and in-app payments.</p>

<p><a href="http://rdfa.info/">Linked Data on the web</a> and new features like <a href="http://beta.yandex.com/">Yandex Islands</a> make it easier to connect web applications and data on the web together. Tools like my <a href="http://createjs.org/">Create.js</a> make the web easier to edit, and <a href="http://webintents.org/">Web Intents</a> promise even closer integration between web apps.</p>

<p>Each of these will make the web richer and better. Each of them will allow new startups to be built, and new meaningful connections to happen over the internet, many of these using mobile devices.</p>

<p>It is an exciting time to be a web developer.</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a3bcc4e60de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a3bcc4e60de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a3bcc4e60de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a3bcc4e60de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Fri, 07 Jun 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a3bcc4e60de9a11e7894e07d57c4b55bb55bb</guid>
        </item>
        <item>
            <title>The mobile-first Web</title>
            <link>http://bergie.iki.fi/blog/mobile-first-web/</link>
            <description><![CDATA[
<p>The growth of mobile web users is staggering. While <a href="http://bergie.iki.fi/blog/meego-diaspora/">some of us</a> have been browsing the web on mobile devices for nearly ten years, most of the world population is only now getting there.</p>

<p>The <a href="http://www.tuaw.com/2013/05/31/internet-trends-report-highlights-ipads-incredible-success-roo/">number of mobile web users</a> is already at 1.5 billion, which happens to be quite close to the <a href="http://www.internetworldstats.com/blog.htm">total number of Internet users</a> back in 2009.</p>

<p>And it is <a href="http://www.fiercemobileit.com/story/global-smartphone-market-growth-estimates-vary-among-research-firms/2013-06-03">growing rapidly</a>. In 2015 there will be an estimated <a href="http://finance.yahoo.com/news/number-smartphones-around-world-top-122000896.html">2 billion smartphone users</a> which is quite close to the total number of Internet users currently.</p>

<p>In the developed world, this is likely to be a mixture of tablets, smartphones, and traditional desktop computers, with most users having at least two different web-capable devices. In the developing world, <em>the smartphone is the computer</em>.</p>

<p>Considering these statistics, <em>it is insanity to design websites and services PC-first</em>, with mobile only as an afterthought.</p>

<h2 id="how-to-prepare">How to prepare</h2>

<p>Just some years ago, the mobile web was a slum. Instead of getting full-featured websites, many sent us out to poorly-built and featureless <a href="http://www.mobify.com/blog/6-reasons-mdot-websites-are-dead-ends/">m. sites</a>. Now more and more sites go with <a href="http://en.wikipedia.org/wiki/Responsive_web_design">responsive web design</a> that makes the site itself adapt to different screen sizes and resolutions.</p>

<p>But even with responsive design, it is easy to go overboard. Tools like <a href="http://jetpack.me/support/mobile-theme/">WordPress Jetpack</a> and <a href="http://jquerymobile.com/">jQuery Mobile</a> oversimplify the site itself by trying to make it look and feel like a native app. In the mobile-first world this is not the right way to go.</p>

<p>In <a href="http://blogs.hbr.org/cs/2013/05/the_rise_of_the_mobile-only_us.html">The Rise of the Mobile-Only User</a> content strategist Karen McGrane makes a valid point (emphasis added):</p>

<blockquote>
  <p>Mobile users should get the same content. It’s frustrating and confusing for them if you only give them a little bit of what you offer on your “real” website. If you try to guess which subset of your content the mobile user needs, you’re going to guess wrong. Deliver the same content as your desktop user sees. (<em>If you think some of your content doesn’t deserve to be on mobile, guess what — it doesn’t deserve to be on the desktop either. Get rid of it.</em>)</p>
</blockquote>

<h2 id="there-is-no-pixel-perfect">There is no pixel-perfect</h2>

<p>In this new world users will access your content or software using a wildly varying set of devices. And each of them has the reasonable expectation of being able to access the full experience and the full set of features you’re providing.</p>

<p>This changes web design substantially. Even in the old world of different PC browsers, <em>pixel perfect web design</em> was rarely that. With responsive design, it is <a href="http://blog.microsecommerce.com/index.php/uncategorized/responsive-design-and-the-demise-of-pixel-perfect/">even less so</a>.</p>

<p>Instead:</p>

<ul>
  <li>Think in <em>visual components instead of full pages</em>. The composition of a page out of these components can vary for different screen sizes</li>
  <li>Design the compositions always for at <em>three screen form factors</em>: a full-sized desktop or tablet screen, a smartphone screen, and the 7” tablet in between</li>
  <li>Make your <em>user interface elements big enough</em> to be used on inaccurate touch screens</li>
  <li><em>Never, ever require a plugin</em> to access some content or functionality</li>
</ul>

<p><a href="http://css-tricks.com/css-media-queries/">CSS Media Queries</a> make responding to different form factors quite easy. And besides that, they also make it easy to optimize for the <a href="http://developer.android.com/training/multiscreen/screendensities.html#TaskProvideAltBmp">different screen densities</a> we now have. This way your images will look sharp on anything the users have, from the “retina-class devices” to the lowest-specced Chinese smartphone, while requiring the user to only download the assets that their device can utilize.</p>

<p>The devices people use to access the services you provide will vary greatly not only in their display capabilities, but also in the ways you can do input. Some will have mice and physical keyboards, but an increasing amount will instead have a touchscreen. For these users, it is a big service to use the correct <a href="http://sixrevisions.com/html5/new-html5-form-input-types/">HTML5 input types</a> so that the on-screen keyboards and widgets can adapt to the content being entered.</p>

<h2 id="the-web-is-not-native">The web is not native</h2>

<p>The web is its own platform, and as such it is <em>foolish to try and mimic traditional desktop applications</em>. It will never feel quite right whatever you do.</p>

<p>It is a lot better to accept this and fully embrace the unique advantages of the web platform:</p>

<ul>
  <li><em>The web is an <a href="http://bergie.iki.fi/blog/the_universal_runtime/">universal runtime</a></em> that works on 100% of the computing devices your users have</li>
  <li><em>There are no gatekeepers</em> telling what you can publish, and <em>no middlemen</em> taking a cut of whatever you sell online</li>
  <li><em>The web is built out of URLs</em> that users can easily share with each other, and continue using when they switch devices</li>
  <li>URLs also allow <em>any application on the web to link to any screen or state of another application</em></li>
  <li>It is just as easy to <em>provide content as it is to provide functional applications</em> on the web</li>
</ul>

<p>Every major software company on the planet has their own web browser, and the competition between these is fierce. This will ensure that over time, the web will keep on getting better and faster. Compare this to traditional software platforms that can easily stagnate or get abandoned. Thanks to the standard protocols it also <em>allows you to use any technology of your choosing</em> for the server side of your software.</p>

<p>Paul Graham put it well in his <a href="http://paulgraham.com/road.html">The other road ahead</a> from 2001:</p>

<blockquote>
  <p>And you don’t have to know if you bet on Web-based applications. No one can break that without breaking browsing. The Web may not be the only way to deliver software, but it’s one that works now and will continue to work for a long time. Web-based applications are cheap to develop, and easy for even the smallest startup to deliver.</p>
</blockquote>

<h2 id="things-are-getting-better">Things are getting better</h2>

<p>As somebody who has been developing for the web for nearly <a href="http://press.web.cern.ch/press-releases/2013/04/cern-celebrates-20-years-free-open-web">twenty years</a> the rate the web developer experience keeps improving is sometimes dizzying.</p>

<p>We get used to some limitations in the stack, and then suddenly something comes along and removes that shortcoming. We’re still exploring the new kinds of designs and visual experiences technologies like Media Queries and <a href="http://en.wikipedia.org/wiki/WebGL">WebGL</a> make possible, just like it took years for the community to find best practices around things like AJAX.</p>

<p>And yet new amazing things keep pouring in. My personal favourite recently has been <a href="http://www.polymer-project.org/">Web Components</a> which gives a standard way to <em>provide reusable widgets on the web</em>, and to do things like <em>data binding and templating</em>. This alone will make a lot of the popular frameworks and libraries obsolete.</p>

<p>Just watch <a href="http://youtu.be/0g0oOOT86NY">this video</a> and see how much easier web development is becoming:</p>

<iframe width="500" height="281" src="https://www.youtube.com/embed/0g0oOOT86NY" frameborder="0" allowfullscreen=""></iframe>

<p>The current work on standardizing <a href="https://payswarm.com/">Web Payments</a> together with more grassroots efforts like <a href="http://bitcoin.org/en/">Bitcoin</a> promise to add better ways to do business on the web. This should remove the last big advantage of native applications in that they’re easier (but very expensive) to monetize via app stores and in-app payments.</p>

<p><a href="http://rdfa.info/">Linked Data on the web</a> and new features like <a href="http://beta.yandex.com/">Yandex Islands</a> make it easier to connect web applications and data on the web together. Tools like my <a href="http://createjs.org/">Create.js</a> make the web easier to edit, and <a href="http://webintents.org/">Web Intents</a> promise even closer integration between web apps.</p>

<p>Each of these will make the web richer and better. Each of them will allow new startups to be built, and new meaningful connections to happen over the internet, many of these using mobile devices.</p>

<p>It is an exciting time to be a web developer.</p>
<span class="net_nemein_favourites">2 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e2cf66e787ca60cf6611e2a0496b9bb2e849f749f7&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e2cf66e787ca60cf6611e2a0496b9bb2e849f749f7/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e2cf66e787ca60cf6611e2a0496b9bb2e849f749f7&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e2cf66e787ca60cf6611e2a0496b9bb2e849f749f7/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Fri, 07 Jun 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e2cf66e787ca60cf6611e2a0496b9bb2e849f749f7</guid>
        </item>
        <item>
            <title>Working on an Android tablet: first six weeks</title>
            <link>https://bergie.iki.fi/blog/six-weeks-working-android/</link>
            <description><![CDATA[
<p>I’ve been <a href="http://bergie.iki.fi/blog/working-on-android/">working full time on my Android workstation</a> for over a month now, and it is time to write an update about it. How has it worked out?</p>

<h2 id="what-ive-been-doing">What I’ve been doing</h2>

<p>I would love to tell stories of working from parks and cafes, like <a href="http://yieldthought.com/post/31857050698/ipad-linode-1-year-later">Mark O’Connor has on his iPad setup</a>, but unfortunately we had a backlash of winter here in Berlin and the warm spring weather only came back this week.</p>

<p>Instead — <a href="http://bergie.iki.fi/blog/all-you-need-is-good-backpack/">quite atypically</a> — I’ve been mostly desk-bound in this time. The <a href="http://iks-project.eu">EU projects</a> that mandated a lot of travel have now ended, and my current projects are more about software development than evangelism.</p>

<p>But that actually makes this experiment even more useful, as it means most of the six week has been actual programming, which is what most of my readers also do.</p>

<p>For those who missed my setup in <a href="http://bergie.iki.fi/blog/working-on-android/">the previous post</a>, this is how it looks in action:</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-desk2.jpg"><img src="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-desk2-small.jpg" alt="Nexus 10 as a programming workstation" /></a></p>

<p>On-screen are <a href="http://tmux.sourceforge.net/">tmux</a>, <a href="http://www.vim.org/">vim</a>, and a <a href="http://gruntjs.com/">Grunt</a> test automation <a href="https://github.com/gruntjs/grunt-contrib-watch#readme">watcher</a> running inside a <a href="http://mosh.mit.edu/">MOSH client</a>.</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-shell.png"><img src="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-shell-small.png" alt="Nexus 10 as a programming workstation" /></a></p>

<p>Here are some things I’ve done in the last month:</p>

<ul>
  <li>Porting the <a href="https://noflojs.org">NoFlo flow-based programming engine</a> to run in both browser and Node.js with the same codebase, including a <a href="http://bergie.iki.fi/blog/sharing-javascript-libraries-node-browser/">tutorial on how others can do the same</a></li>
  <li>Writing and publishing an implementation of <a href="http://bergie.iki.fi/actionbar/">Android-style Action Bars for web apps</a></li>
  <li>Adding multiple major features to the <a href="https://github.com/noflo/noflo-ui">web-based NoFlo IDE</a></li>
  <li>Dealing with the issues raised with the release of jQuery UI 1.10 and Backbone 1.0.0 with <a href="http://createjs.org">Create.js</a> and <a href="http://viejs.org">VIE</a></li>
  <li>Blogging, including publishing <a href="http://bergie.iki.fi/blog/no-smartphones/">some</a> <a href="http://bergie.iki.fi/blog/wordpress-decoupled/">quite</a> <a href="http://bergie.iki.fi/blog/working-on-android/">popular</a> posts</li>
</ul>

<p>In general the experience has been a positive and productive one. I’ll write about some nuances here.</p>

<h2 id="web-debugging">Web debugging</h2>

<p>As you can see from the list above, much of my recent work has been client-side. With this, the unavailability of web debuggers on mobile browsers can become a problem.</p>

<p>I’ve tackled this issue in two ways:</p>

<ul>
  <li><em>More tests</em>. Instead of poking around in a debugger, I try to write <a href="http://visionmedia.github.io/mocha/">Mocha tests</a> for most aspects of my applications. This also has the benefit of automation, meaning that <a href="http://phantomjs.org/">PhantomJS</a> will test everything in my application every time I commit</li>
  <li><em>VNC and desktop browsers</em>. When I really need one, I can still use the web debugging tools of traditional web browsers via VNC</li>
</ul>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-vnc.png"><img src="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-vnc-small.png" alt="Web debugging via VNC" /></a></p>

<p><a href="http://yieldthought.com/post/12638596672/setting-up-an-ipad-linode">See Mark O’Connor’s setup instructions</a> for VNC on one of these tablet workstation setups.</p>

<h2 id="post-pc-means-post-office">Post-PC means post-Office</h2>

<p>One area where tablets are really lacking is support for traditional office tools like word processors and spreadsheets. There is a Google Drive client, but it is very slow (even small spreadsheets can take minutes to load) and mostly non-functional (word processor doesn’t even support headlines).</p>

<p>There are also some <a href="http://androidheadlines.com/2012/05/featured-top-10-android-office-suites.html">other office suites</a> available, but even these are better used for viewing documents than actually making changes to them.</p>

<p>But the bigger question is whether traditional office tools even have a place in this modern world. The commentary on constant <a href="http://macsparky.com/blog/2011/11/30/microsoft-office-and-the-ipad.html">delays with Microsoft Office for iOS and Android</a> shows that people don’t see them as that relevant any longer:</p>

<blockquote>
  <p>For the longest time, Office was the ubiquitous productivity suite. Everybody used it. Nobody considered using anything else. However, since this mobile revolution started, even non-geeks are starting to question whether Office is still <em>all that</em>. I had breakfast this morning with a CPA who does all of his work in Google docs. There is an entire generation of future workers going through high school and college now who don’t even have Office installed on their computers. If Microsoft has any hopes of keeping Office relevant, it needs to be everywhere, including the iPad.</p>
</blockquote>

<p>Personally, I might be a lot better off writing my documents in <a href="http://daringfireball.net/projects/markdown/">Markdown</a>, versioning them with git, and maybe using custom data-gathering applications with <a href="http://bergie.iki.fi/blog/business_analytics_with_couchdb_and_noflo/">CouchDB map-reduces for data visualization</a>.</p>

<p>The <a href="http://bergie.iki.fi/blog/tablet-productivity/">story of tablet productivity</a> is still evolving. The new tools and interaction techniques we have will eventually give rise to new kinds of productivity applications. That may signal the end of the Office hegemony.</p>

<h2 id="presenting-from-the-tablet">Presenting from the tablet</h2>

<p>On the first week of this experiment I was actually traveling. The final review meetings for both of the EU projects were being held in Brussels and Luxembourg, and I had to present our results.</p>

<p>As the presentation tools on Android are not very good, I took this as an opportunity to finally start using an HTML-based presentation system. For this, I picked <a href="http://paulrouget.com/dzslides/">DZSlides</a>, with a custom Jekyll-based flow for constructing slide decks from <a href="https://github.com/bergie/talks">individual assets stored in git</a>.</p>

<p>The results are <a href="http://bergie.iki.fi/talks/2013/jquery-europe/">quite nice</a>, and I love being able to <a href="http://bergie.iki.fi/talks/2013/jquery-europe/#12.0">embed live demos</a> inside the slides.</p>

<iframe src="http://bergie.iki.fi/talks/shells/embedder.html#http://bergie.iki.fi/talks/2013/jquery-europe" width="460" height="345"></iframe>

<p>With every computing platform, there is always some fiddling involved with getting your device connected to a beamer. I was positively surprised with how easily the Nexus 10 worked. Simply connect using a <em>micro-HDMI to VGA</em> adapter, and you’ll have the tablet screen up on the projector.</p>

<h2 id="minor-annoyances">Minor annoyances</h2>

<p>Everybody knows about the <a href="http://www.businessinsider.com/google-lacking-android-tablet-apps-2012-11">common gripes with Android on large tablets</a> — most apps have been written with a narrow phone screen in mind, and simply look bad on a wide 10” screen. <a href="https://twitter.com/bergie/status/319710122349838336">Twitter is a good example</a> of the typical neglect of <a href="http://developer.android.com/design/index.html">Android’s UI guidelines</a>.</p>

<p>Somewhat surprisingly, this even applies to Google’s own tablet applications. Apps like Google+ and Google Drive are a lot more functional on an iPad than on a large Android tablet.</p>

<p>However, these are more of a problem when using something like my <a href="http://www.google.com/nexus/10/">Nexus 10</a> as a <em>media tablet</em>, and don’t really affect how well it works as a <em>programming workstation</em>.</p>

<p>For programming work, what matters is things like the beautiful screen, Android’s reasonably good support for hardware keyboards, user-accessible file system, and the ability to share information between applications. These are the main reasons why I went with Android instead of an iPad.</p>

<p>However, not all is sunshine. So far, the main annoyances for me have been:</p>

<ul>
  <li><a href="https://code.google.com/p/android/issues/detail?id=39665">Regressions in Magic Trackpad support</a> mean that it is practically unusable when you also have a Bluetooth keyboard. A lot of character presses get duplicated, making typing near-impossible. I’m assuming other mouse devices would however work</li>
  <li><a href="http://dan.drown.org/android/mosh/">MOSH ConnectBot</a> — which I’m using for my programming sessions — makes <a href="https://code.google.com/p/irssi-connectbot/issues/detail?id=26">Ctrl and Esc keys not work</a>. Luckily I was able to <a href="https://code.google.com/p/irssi-connectbot/issues/detail?id=26#c4">find a workaround</a></li>
  <li>Android 4.2.2 is buggy on the Nexus 10. Especially <a href="http://forums.androidcentral.com/google-nexus-10-tablet/254863-chrome-causes-my-crashes.html">Chrome can cause the system to crash</a>. Other browsers help here, and hopefully Google will fix the issue soon</li>
</ul>

<p>Now, crashes and freezes may sound like a big deal. But thanks to using <a href="http://tmux.sourceforge.net/">tmux</a>, they just mean a short interruption, and not any lost work. I just restart my tablet or MOSH client, attach back to the tmux session I was working with, and I’m right back to where I was, cursor position, vim splits, and all.</p>

<h2 id="quantifying-productivity">Quantifying productivity</h2>

<p>Calculating <a href="http://en.wikipedia.org/wiki/Programming_productivity">programming productivity</a> is notoriusly difficult. While <a href="http://yieldthought.com/post/31857050698/ipad-linode-1-year-later">Mark was able to show impressive figures</a> from his iPad setup, I don’t have anything similar because:</p>

<ul>
  <li>I haven’t had the time to <a href="http://yieldthought.com/post/6070927890/metagame-productivity-boost-stats-and-charts">crunch the numbers</a> on the work I do</li>
  <li>The ending of the EU projects meant that I’m now doing different things than I did with my laptop, and so comparing results from the two is hard</li>
</ul>

<p>And in the end what matters more is the results of the work, not the effort spent getting there.</p>

<p>But still, it would be good to have a bit more data on how well the setup works besides the subjective “<em>it feels like a good way to program</em>”.</p>

<p>To this end, I recently started using the <a href="https://www.rescuetime.com/">RescueTime</a> tracker on both of my Android devices. It keeps calculates how much time I spend with different applications each day, and even allows me to give some sort of productivity scores for them:</p>

<p><a href="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-rescuetime.png"><img src="https://d2vqpl3tx84ay5.cloudfront.net/nexus10-rescuetime-small.png" alt="Scoring applications on RescueTime" /></a></p>

<p>I’ll be running this for a while, and will try to combine it with some statistics from <a href="https://github.com/bergie">my GitHub account</a>. Those two should be able to paint a picture of how I work.</p>

<h2 id="conclusions">Conclusions</h2>

<p>In the beginning, like with any new tool you have to start using, the Android tablet setup felt weird and limiting. But it has grown on me since, and right now <em>I’m not regretting giving my laptop away.</em></p>

<p>But at the same time, if a new interesting device came out, the cost of switching to that would be minimal. After all, the Nexus 10 for me is essentially just a window into the web and my terminal running somewhere else.</p>

<p>In a way this decoupling is similar to the traditional desktop PC setup where you have a separate computer, screen, mouse, and a keyboard. The difference here is that none of those parts are bound to a desk or connected with cables. Instead, the peripherals talk with my screen over Bluetooth, and my screen with the “computer” over the Internet.</p>

<p>If I for instance want a <a href="http://matias.ca/laptoppro/mac/">better keyboard</a>, I can just buy one and replace that part without having to change anything else with my setup.</p>

<h3 id="cost-advantage">Cost advantage</h3>

<p>One aspect that people have remarked on is cost. Over the course of two years — which is the typical replacement cycle of a professional workstation — this setup is cheaper than a <a href="http://bergie.iki.fi/blog/11-macbook_air-the_best_computer_i-ve_ever_had/">MacBook Air</a>. And with that price I get a lot better screen and about double battery life, and even a smartphone.</p>

<p>What I lose is the ability to work fully offline, though somewhat alleviated by having local vim and git via <a href="https://play.google.com/store/apps/details?id=com.spartacusrex.spartacuside&amp;hl=en">Terminal IDE</a>.</p>

<h3 id="moving-forward">Moving forward</h3>

<p>The experiment will keep continue. In these six weeks, I haven’t seen any negative impact on my productivity from working on an Android tablet instead of a laptop, and many positive ones. <em>Portability, battery life, and the emphasis on tests and automation</em> are probably the foremost.</p>

<p>Of course, new devices come to the market, and eventually something will come that beats the current setup. But then I’ll be able to switch without even losing my cursor position, so the only cost is the hardware itself.</p>

<p>In time, I will write more about how things are going.</p>

<p><strong>Update:</strong> Read my <a href="https://bergie.iki.fi/blog/working-on-android-2017/">Working on Android, 2017 edition</a> post.</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a392ba12ede9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a392ba12ede9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a392ba12ede9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a392ba12ede9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Tue, 16 Apr 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a392ba12ede9a11e7894e07d57c4b55bb55bb</guid>
        </item>
        <item>
            <title>There are no smartphones</title>
            <link>https://bergie.iki.fi/blog/no-smartphones/</link>
            <description><![CDATA[
<p>iPad is three years old now, and many tech blogs are writing stories <a href="http://arstechnica.com/gadgets/2013/04/i-was-an-ipad-skeptic/">to reflect what has changed</a>. More than 100 million of them have been sold, alongside other popular tablets like the Kindle Fire and Nexus 7. But originally the reception was quite sceptical.</p>

<p>Many made the argument that the tablet was <em>“<a href="http://www.pcworld.com/article/187888/ipad_first_impressions.html">just a big iPod Touch</a> or iPhone”</em>:</p>

<blockquote>
  <p>at the end of the day, the show’s centerpiece - the iPad – is just a big iPod Touch. Lots of folks will want it, in a hypothetical sort of way. But it’s hard to imagine all that many of them will fork over the initial $499 for a crippled version</p>
</blockquote>

<p>The funny thing about this argument is that — while the skepticism was misplaced — the core point was true: The iPad is just a big iPhone.</p>

<p>Or to put it the other way, <em>the iPhone is just a pocket-sized iPad.</em></p>

<h2 id="tablets-of-different-sizes">Tablets of different sizes</h2>

<p>There was a recent <a href="http://techland.time.com/2013/04/02/an-interview-with-computing-pioneer-alan-kay/">Time interview of the computer science legend Alan Kay</a>. I shared it <a href="https://plus.google.com/100751105859582805241/posts/G2XKvZEJjDJ">on Google+</a>, and there was some discussion. I made the following argument:</p>

<blockquote>
  <p>In the end there are no phones any longer. Just tablets of different sizes, from tabletop (iPad, Surface) to pocketable (what we call smartphones)</p>
</blockquote>

<p>The chances are that if you’re reading this post, you will have what you consider a smartphone. Look at it, and consider how you use it. Is it really a <em>phone</em>, or is the way you use it a lot closer to what you’d consider a <em>tablet</em>?</p>

<p>Back in mid-to-late 2000s, we had <a href="http://bergie.iki.fi/blog/meego-diaspora/">Nokia’s Internet Tablet devices</a>. We considered them tablets, and did tablet-like things on them. The Nokia 770 tablet had a 4.13” screen. The iPhone has a 4” screen, and the Nexus 4 has a 4.7” screen. And yet somehow the first device was seen as a tablet, and the two latter as smartphones.</p>

<p>The software running on smartphones and tablets is nearly identical, as are the use cases.</p>

<h2 id="phablets-meet-in-the-middle">Phablets meet in the middle</h2>

<p>Smartphones and tablets are converging, quickly. Manufacturers know this, and the device-buying public is starting to see it too. But still the <a href="http://arstechnica.com/gadgets/2013/04/a-massive-6-3-inch-smartphone-from-samsung-may-be-in-the-works/">gadget blogs love to diss</a> the large <em>“phablet”</em> devices, even though they <a href="http://arstechnica.com/gadgets/2012/03/samsung-announces-5-million-galaxy-notes-sold-and-premium-update-upgrade/">sell quite well</a>.</p>

<p>The problem here is that many technology bloggers still try to keep the two categories of devices — smartphones and tablets — separate, even though they really aren’t. Maybe these devices are two big for holding against your head for a phone call, but who really does that anymore?</p>

<p>In reality all of them are tablets — <a href="http://alistapart.com/column/windows-on-the-web">windows on the web</a> — and the only difference is that some of them fit in your pocket, and others need a bag, providing a bigger canvas to see information and work on in exchange.</p>

<p>This is the use case I have. For most of my internet and communication needs, I’m using a Nexus 4 as a pocketable tablet. I also have a larger tablet, which I <a href="http://bergie.iki.fi/blog/working-on-android/">use as my workstation</a> and for some things where a bigger screen is nicer, like graphic novels.</p>

<p>Some are even <a href="http://www.citeworld.com/mobile/21577/man-did-all-his-work-smartphone-one-year-heres-what-he-learned">able to do all their work on the smaller phablets</a>.</p>

<h2 id="end-of-telephony">End of telephony</h2>

<p>The big news here is that the <em>telephony</em> part of a smartphone is not going to matter for much longer. Internet-based communication tools like instant messengers, email, and hangouts provide richer ways to interact, and don’t tie you down to a specific device, or a specific telecommunications provider.</p>

<p>In the long run, this means an end to phone subscriptions. As I wrote <a href="http://bergie.iki.fi/blog/toolkit-2012/">on my “hacker’s toolkit”</a>, buying prepaid data is cheaper and easier:</p>

<blockquote>
  <p>As the MiFi is only used for Internet access, I can buy cheap pre-paid SIMs from each country I travel to. Paying somewhere around ten euros for a month of Internet abroad certainly beats the usual roaming charges!</p>
</blockquote>

<p>This is already happening. For example, <a href="http://www.asymco.com/2013/01/18/whats-up-with-text-messaging/">Asymco reported on dropping SMS volumes in Spain</a>:</p>

<blockquote>
  <p>After peaking at the end of 2008 at about €450/quarter, revenues have fallen by 60% to about €171 million in the third quarter of 2012. These figures represent almost 100% operating profit for operators so the impact is felt directly in the bottom line.</p>
</blockquote>

<blockquote>
  <p>The culprit is IP-based messaging. Services like Whatsapp, iMessage and even Facebook offer “free” messaging to users who have a smartphone and a data plan. I’ve been told that 97% of Spanish smartphone users have Whatsapp installed. In some markets this “free” messaging is offered via BlackBerry Messaging.</p>
</blockquote>

<p>This obviously is a development telecommunications companies are scared of. But while SMS and call volumes go down, the other change is that <em>all these new devices will have SIM slots</em>, and so the operators can sell a lot more of data plans.</p>

<p>Some of them are already targeting this new world. <a href="http://mobile.slashdot.org/story/13/03/26/2048233/t-mobile-ends-contracts-and-subsidies">T-Mobile recently killed their traditional subscriptions and subsidies</a> in favor of prepaid plans.</p>

<h2 id="this-is-a-new-world">This is a new world</h2>

<p>The computing world is <a href="http://bergie.iki.fi/blog/why_the_tablet_form_factor_is_winning/">switching to tablets</a> rapidly. These tablets can be smaller or bigger depending on the requirements of the user, but they all are internet-connected, touch-capable and full of sensors. They already fit use cases from <a href="http://yieldthought.com/post/31857050698/ipad-linode-1-year-later">software development</a> to watching media or social networking.</p>

<p>This will mean <a href="http://al3x.net/2011/01/10/a-thought-on-communication.html">eventual changes in our culture</a>:</p>

<blockquote>
  <p>My generation will be at something of a loss when this new world comes about. In my life, I’ve been rewarded for communicating effectively online via text. I’m a reasonably effective verbal communicator, but not nearly as good as I’ll need to be to compete with the telepresence-native adults that the children of today will grow up to be.</p>
</blockquote>

<blockquote>
  <p>Today’s digital natives will be tomorrow’s telegraph operators. The only way to survive will be to understand the impact of pervasive video communication before it sweeps us under our keyboards.</p>
</blockquote>

<p>PCs will still remain as the main productivity tool for some years, mainly thanks to all the legacy software built around that ecosystem. But the <a href="http://bergie.iki.fi/blog/tablet-productivity/">VisiCalc moment of tablets</a> will come, sooner or later:</p>

<blockquote>
  <p>Every major shift in computing has brought its new big companies. PCs gave us Microsoft, web Google and Facebook. In the tablet space the focus has so far been on hardware and platforms, but I’m quite certain there will be winners in the productivity software space as well, companies that we may not have even heard of yet. Maybe your company is going to be one of them?</p>
</blockquote>

<p>For now, I’m considering my adventures in the tablet productivity world an experiment. But day by day, my <a href="http://bergie.iki.fi/blog/working-on-android/">work tablet setup</a> is feeling more and more comfortable.</p>

<p>Right now I don’t miss my laptop. Or having a phone number.</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a3679ca00de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a3679ca00de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a3679ca00de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a3679ca00de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Wed, 03 Apr 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a3679ca00de9a11e7894e07d57c4b55bb55bb</guid>
        </item>
        <item>
            <title>Google Glass and the fear of the future</title>
            <link>https://bergie.iki.fi/blog/google-glass-future/</link>
            <description><![CDATA[
<p><a href="http://www.google.com/glass/start/">Google Glass</a> is coming this year, a wearable display that can keep you connected at all the times and supply information and instructions when you need them. And it can record video or take pictures of whatever you see, when you want it to.</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/v1uyQZNg2vE" frameborder="0" allowfullscreen=""></iframe>

<h2 id="the-privacy-scare">The privacy scare</h2>

<p>Much of the <a href="http://www.google.com/glass/start/how-it-feels/">Glass marketing</a> focuses on the camera aspect, as does the <a href="http://stopthecyborgs.org/about/">criticism and fearmongering</a> around it. Some feel that the device would bring about an era of ubiquitous surveillance and loss of privacy. Some even label these people <a href="http://www.internetevolution.com/author.asp?section_id=2724&amp;doc_id=260938&amp;">as Luddites</a>:</p>

<blockquote>
  <p>StopTheCyborgs and other Neo-Luddite groups make some pretty compelling arguments against AR, including the credible threat that people could be recorded at any time without their knowledge or permission. Nobody could ever consider conversation in the presence of Google Glass wearers completely private. Any entity that could tap into and process all the information from Google Glass on a minute-to-minute basis could track anyone or any conversation anywhere near the wearers. Google Glass may well begin the destruction of our current definitions of privacy.</p>
</blockquote>

<p>The mislabeling aside (the historical Luddites were more concerned about machinery taking away their jobs, as they and globalization together eventually did), the criticism is generally baseless.</p>

<p>We live in cities filled with thousands of surveillance cameras monitoring our every move. We pay for our groceries with credit cards that leave a mark on everything you bought — when, and where — into a database. We carry smartphones that are constantly reporting their location back to the operator. We post our private pictures and current activities to social networks. There is very little privacy left. If you’d see how detailed information law enforcement can get out of our every movement from your operator, you’d know that too.</p>

<p>In a world where a hidden, <a href="http://www.pathgadget.com/spy-pen-page-1.html">pencil-shaped spy camera</a> can be bought for about 30$, is a very obviously visible Google Glass device really the biggest risk to privacy? And yet, <a href="http://arstechnica.com/gadgets/2013/03/seattle-bar-bans-google-glass-still-loves-beer-goggles/">places are banning them</a> already, a lot before they actually hit the market.</p>

<h2 id="this-is-the-future">This is the future</h2>

<p>The anti-Glass movement has a benefit. While not exactly a flying car, it is yet another sign that we’re living in the future that science fiction authors envisioned. I mean, consider the fact that there is A <em>movement to ban cyborgs</em>.</p>

<p><img src="https://d2vqpl3tx84ay5.cloudfront.net/surveillance-ban.png" alt="Stop the Cyborgs" /></p>

<p>They even <a href="http://www.redbubble.com/people/stopthecyborgs">sell stickers</a>.</p>

<h2 id="consider-the-possibilities">Consider the possibilities</h2>

<p>Since the privacy battle is already lost, shouldn’t we instead focus on the possibilities they can bring? While Google has shown very little of the capabilities of the Glass software apart from videoconferencing and making web searches, various books can provide clues.</p>

<p>Many of them describe a world where you can share with anybody what you see with your own eyes, or access any information without having to hold a bulky device.</p>

<p>It is a little hard to provide good context of the use cases from the books just by short snippets, but here are some. Feel free to provide your own in the comments.</p>

<p>In Daniel Suarez’s <a href="http://en.wikipedia.org/wiki/Daemon_%28technothriller_series%29">Daemon series</a>, Glass-like devices are used for connecting and coordinating a full economy, called the Darknet. Here is a view of an office with augmented reality displays and <a href="https://www.leapmotion.com/">motion controls</a>:</p>

<blockquote>
  <p>The center of the room looked to be a staging area, bustling with your people, all wearing eyewear and gloves. To the side was a raised platformn lined with office chairs where a dozen people were grabbing, pulling, and pushing at invisible objects in the air. They were all speaking to unseen people, as though it were a call center.</p>
</blockquote>

<p>I could easily imagine manipulating my <a href="https://noflojs.org">flow based programs</a> in this way.</p>

<p>The Daemon series also feature other Google products, like <a href="http://en.wikipedia.org/wiki/Google_driverless_car">driverless cars</a> and an augmented reality game much like <a href="http://www.ingress.com/">Ingress</a>.</p>

<p>Vernor Vinge’s <a href="http://en.wikipedia.org/wiki/Rainbows_End">Rainbows End</a> has everybody using augmented reality glasses as an everyday matter. They even change how you see a city like Barcelona:</p>

<blockquote>
  <p>Vaz strolled to the stone barrier and looked down. If he blocked out all the tourism fantasy [augmented by the Glass], he could see the freight harbor almost two hundred meters below and a kilometer away. The place was an immensity of freight containers rambling this way and that, chaos. If he invoked his government powers, he could see the flow of carge, even see the security certificates…</p>
</blockquote>

<p>And of course people interact with the augmented reality projections of others just like they were present:</p>

<blockquote>
  <p>Even when her friends were gone physically, they were often still around, invisible presences [without the Glass] like Robert’s doctors. Miri walked around the backyard talking and arguing with nobody—a parody of all the cellphone discourtesy that Robert remembered</p>
</blockquote>

<p>For the less pleasant view of something like Glass, Neal Stephenson’s <a href="http://en.wikipedia.org/wiki/Snow_Crash">Snow Crash</a> focuses on the surveillance aspects, with people using AR displays being called <em>Gargoyles</em>:</p>

<blockquote>
  <p>Gargoyles are no fun to talk to. They never finish a sentence. They are adrift in a laser-drawn world, scanning retinas in all directions, doing background checks on everyone within a thousand yards, seeing everything in visual light, infrared, millimeter-wave radar, and ultrasound all at once. You think they’re talking to you, but they’re actually poring over the credit record of some stranger on the other side of the room, or identifying the make and model of airplanes flying overhead.</p>
</blockquote>

<p>Then again, talking with a Facebook addict can already be a lot like that.</p>

<h2 id="how-this-will-play-out">How this will play out</h2>

<p>If the glass does what people want it to do, it will become popular.</p>

<p>Just like we’ve taken smartphones and tablets into our lives and homes, eventually we will live in a world where you will feel naked if you step out of your home door without the glass on. <em>How am I supposed to connect and communicate now?</em></p>

<p>I’d love to have Glass, even if it is clunky in the beginning.</p>

<p>Wearable computing is one of the possible trajectories we’re going with, from room-sized mainframes to desk-bound personal computers to these amazing small slabs of glass and antennas we now carry in our pockets.</p>

<p>Just like with <a href="http://bergie.iki.fi/blog/smart-collaboration-space/">smart spaces</a>, or <a href="http://bergie.iki.fi/blog/the-real-hitchhiker-s-guide-to-the-galaxy/">tablets many years ago</a>, I’m keen to explore the new interaction possibilities.</p>
<span class="net_nemein_favourites">0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=fav&net_nemein_favourites_execute_for=1e7de9a33f16630de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/fav/midgard_article/1e7de9a33f16630de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-favorite.png" style="border: none;" alt="Add to favourites" title="Add to favourites" /></a>0 <a href="http://maemo.org/news/?net_nemein_favourites_execute=bury&net_nemein_favourites_execute_for=1e7de9a33f16630de9a11e7894e07d57c4b55bb55bb&net_nemein_favourites_url=https://maemo.org/news/favorites//json/bury/midgard_article/1e7de9a33f16630de9a11e7894e07d57c4b55bb55bb/" class="net_nemein_favourites_create"><img src="http://static.maemo.org:81/net.nemein.favourites/not-buried.png" style="border: none;" alt="Bury" title="Bury" /></a></span>]]></description>
            <author>Henri Bergius &lt;henri.bergius@iki.fi&gt;</author>
            <category>feed:766d7361580352c5efed0204e4ba8593</category>
            <pubDate>Fri, 22 Mar 2013 00:00:00 +0000</pubDate>
            <guid>http://maemo.org/midcom-permalink-1e7de9a33f16630de9a11e7894e07d57c4b55bb55bb</guid>
        </item>
    </channel>
</rss>
